home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
001
/
jmodem.arc
/
JMODEM.LST
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
File List
|
1988-09-13
|
98.7 KB
|
2,064 lines
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-1
1 PAGE ,132
2 TITLE JMODEM.ASM
3 ;
4 COMMENT *
5 Created 02-SEP-1988 Richard B. Johnson
6
7 Purpose:
8 File transfer protocol. Use with BBS systems and communications
9 programs that allow "external protocols".
10 This program will transfer a single file between the host and an
11 IBM compatible microcomputer. It will use data-compression when the
12 data can be compressed and transfers data uncompressed should comp-
13 ression techniques fail to reduce the block-size.
14
15 The block-size is variable, ranging from 512 bytes (plus a 6-byte
16 overhead) to 8192 bytes (plus a 6-byte overhead). The block-size
17 is increased up to the limit if there are no transmission errors.
18 Should errors occur, the block-size is reduced to a minimum of 512
19 bytes. Since the bytes transferred may be of any length, the file-
20 size is exactly correct after the file is received.
21
22 Data compression is used when its been found that the compression
23 will reduce the size of the transmitted blocks. Flow control is
24 also provided to interface with high-speed modems. The flow-control
25 techniques used are invisible to the user so no special provisions
26 are necessary. You don't have to add anything on the command line.
27
28 Usage:
29 JMODEM S1 <filename.typ> (to send a file via COM1)
30 JMODEM R1 <filename.typ> (to receive a file via COM1)
31 JMODEM S2 <filename.typ> (to send a file via COM2)
32 JMODEM R2 <filename.typ> (to receive a file via COM2)
33
34 Known bugs(?)
35 Since the DOS function 9 is used to print many strings, filenames
36 that contain a '$' will be incompletely displayed on the screen.
37 This will be fixed in the second minor revision.
38
39 Modification record: Release 04-SEP-1988
40
41 05-SEPT-1988 Richard B. Johnson V1.01
42 Added interrupt on receive routines so that data could be received
43 while the file is being written.
44
45 07-SEPT-1988 Richard B. Johnson V1.02
46 Added checks for an abort in the flow-control routine. This should
47 prevent long time-outs if one end aborts.
48
49 07-SEPT-1988 Richard B. Johnson V1.02
50 Fixed bug (typo) in source code that prevented operation on COM2.
51 Port address 2F8H was mispelled to 02FH which prevented operation
52
53 08-SEPT-1988 Richard B. Johnson V1.03
54 Added a status window with direct writes to the screen to reduce
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-2
55 the time necessary to show the TX/RX status
56
57 Changed the local variable [CLOCK] to a word and increased the sync
58 interval to allow slow users more time to get their files ready for
59 TX.
60
61 10-SEPT-1988 Richard B. Johnson V1.04
62 Fixed the print string routines so that a '$' can be displayed.
63 Also streamlined the FLOW control routine so a port need not be
64 read. Interrupts are now enabled for modem status as well as data
65 ready. Modem status is read and put in memory so FLOW control need
66 only check memory.
67
68 13-SEPT-1988 Richard B. Johnson V1.05
69 Added support for COM3 and COM4. Note that there are no IBM standards
70 denoting where the port addresses are for COM3 and COM4. They have
71 been put where most communications programs seem to have put them.
72
73 Note:
74 This must be linked as a '.COM' file.
75 MASM JMODEM;
76 LINK JMODEM;
77 EXE2BIN JMODEM.EXE JMODEM.COM
78 DEL JMODEM.EXE
79 *
80 ;
81 ELSE
82 %OUT [PASS2]
83 ENDIF
84 ;
85 VERS STRUC
86 0000 56 31 2E 30 35 DB 'V1.05'
87 0005 VERS ENDS
88 ;
89 = 0070 SCRATTR EQU 01110000B ; Screen attribute
90 = 0012 TIMOUT EQU 18 ; About 1 second
91 = 000A MAX EQU 10 ; Max retries
92 = 0021 MS_DOS EQU 21H ; MS-DOS functions
93 = 0010 VIDEO EQU 10H ; Video BIOS routines
94 = 000D CR EQU 0DH ; ASCII
95 = 000A LF EQU 0AH ; ASCII
96 = 4000 CODELOC EQU 16384 ; Where to code/decode data
97 = 8000 HOME EQU CODELOC + 16384 ; Interrupt buffer
98 = 0021 INT_CTL EQU 21H ; Interrupt controller address
99 = 000C INT_1 EQU 0CH ; For COM1
100 = 000B INT_2 EQU 0BH ; For COM2
101 = 00EF IRQ4 EQU 11101111B ; For COM1
102 = 00F7 IRQ3 EQU 11110111B ; For COM2
103 = 0001 INT_RC EQU 00000001B ; Interrupt on received character
104 = 0008 INT_MS EQU 00001000B ; Interrupt on modem status
105 = 0004 RDAT EQU 00000100B ; Received data available
106 = 0008 TRISTAT EQU 00001000B ; Turn on tristate buffer
107 = 0003 RTS_DTR EQU 00000011B ; DTR/RTS bits
108 ;
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-3
109 ; Parameters for Various communications adapter ports.
110 ;
111 COM1 STRUC
112 0000 03F8 COM1PRT DW 03F8H ; Base port
113 0002 0C COM1INT DB INT_1 ; IRQ4
114 0003 EF COM1MSK DB IRQ4 ; Controller mask
115 0004 COM1 ENDS
116 ;
117 COM2 STRUC
118 0000 02F8 COM2PRT DW 02F8H ; Base port
119 0002 0B COM2INT DB INT_2 ; IRQ3
120 0003 F7 COM2MSK DB IRQ3 ; Controller mask
121 0004 COM2 ENDS
122 ;
123 COM3 STRUC
124 0000 03E8 COM3PRT DW 03E8H ; Base port
125 0002 0C COM3INT DB INT_1 ; IRQ4
126 0003 EF COM3MSK DB IRQ4 ; Controller mask
127 0004 COM3 ENDS
128 ;
129 COM4 STRUC
130 0000 02E8 COM4PRT DW 02E8H ; Base port
131 0002 0B COM4INT DB INT_2 ; IRQ3
132 0003 F7 COM4MSK DB IRQ3 ; Controller mask
133 0004 COM4 ENDS
134 ;
135 IBUFFER STRUC
136 0000 ???? LEN DW ? ; String length
137 0002 ?? CTRL DB ? ; Control byte
138 0003 ?? RECN DB ? ; Record number
139 0004 ?? IDATA DB ? ; Start of data
140 0005 IBUFFER ENDS
141 ;
142 ; Control byte context
143 ;
144 = 0001 NORMAL EQU 00000001B ; Normal data
145 = 0002 COMP EQU 00000010B ; Compressed data
146 = 0004 EOF EQU 00000100B ; End of file
147 = 0008 RETRY EQU 00001000B ; Ask/respond with retry
148 = 0010 TIMEOUT EQU 00010000B ; Informational
149 = 0020 ABORT EQU 00100000B ; Kill U/D load
150 = 0040 SYNC EQU 01000000B ; Hello /ack
151 = 0080 ERROR EQU 10000000B ; Undefined error
152 = FFFE NONORM EQU NOT NORMAL ; Invert 'NORMAL' bits
153 ;
154 ; UART equates.
155 ;
156 = 0001 DR EQU 00000001B ; Data ready
157 = 0010 CTS EQU 00010000B ; Clear to send
158 = 0020 DSR EQU 00100000B ; Data set ready
159 = 0020 THRE EQU 00100000B ; TX holding register empty
160 = 0080 RLSD EQU 10000000B ; Rec. line signal det
161 = 0030 CTSDSR EQU CTS OR DSR
162 ;
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-4
163 ; Control bytes.
164 ;
165 = 0006 ACK EQU 'F' - 64
166 = 0015 NAK EQU 'U' - 64
167 = 0004 EOT EQU 'D' - 64
168 = 0018 CAN EQU 'X' - 64
169 = 0016 SYN EQU 'V' - 64
170 ;
171 ; BIOS segment structure.
172 ;
173 0000 BSEG SEGMENT AT 40H
174 0063 ORG 63H
175 0063 ???? ADDR_6845 DW ? ; Address of the video controller
176 0065 BSEG ENDS
177 ;
178 = 03F6 ORIGIN EQU 1014 ; Where to put the status box
179 = 0017 LINLEN EQU 23 ; Length of a line
180 = 054C SCR_BLK EQU ORIGIN + ( (160 - (LINLEN *2) ) * 3) ; Offset to block count
181 = 05EC SCR_LEN EQU SCR_BLK + 160 ; Offset to block length
182 = 068C SCR_BYT EQU SCR_LEN + 160 ; Offset to byte count
183 = 072C SCR_CPS EQU SCR_BYT + 160 ; Offset to chars/sec
184 = 055E SCR_ACK EQU SCR_BLK + 18 ; Where to put ACK/NAK
185 ;
186 0000 PSEG SEGMENT PARA PUBLIC 'CODE'
187 = 0000 START EQU $
188 ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:NOTHING
189 0100 ORG 100H
190 0100 MAIN PROC NEAR
191 0100 BC 0E80 R MOV SP,OFFSET STACKP ; Keep stack pointer safe
192 ;
193 0103 BF 09DD R MOV DI,OFFSET KILL ; First variable to zero out
194 0106 B9 000E 90 MOV CX,KLEN ; Length of the variable list
195 010A 32 C0 XOR AL,AL ; Get a zero
196 010C F3/ AA REP STOSB ; Set all to zero
197 ;
198 010E E8 0990 R CALL FIND_VIDEO ; Find the video segment
199 0111 E8 0477 R CALL SET_SEG ; Set up data segment
200 0114 E8 0764 R CALL PARSE ; Parse the command line
201 0117 73 0E JNC WASOK ; Commands okay
202 0119 E8 08F3 R CALL SENDX ; Tell other end to quit
203 011C BE 0AB5 R MOV SI,OFFSET PRP3 ; Point to 'usage' prompt
204 011F E8 03D9 R CALL PROMPT ; Print to screen
205 0122 B8 4C01 MOV AX,4C01H ; Terminate with error
206 0125 CD 21 INT MS_DOS
207 ;
208 0127 33 C0 WASOK: XOR AX,AX ; Get current time
209 0129 CD 1A INT 1AH ; Get the time
210 012B 89 16 09DB R MOV WORD PTR [TIM_L],DX ; Save new LOW count
211 012F 80 3E 09EE R 53 CMP BYTE PTR [RXTX],'S' ; Do we want to send?
212 0134 74 03 JZ SEND ; Yes
213 0136 E9 01CA R JMP RECV ; Else receive
214 0139 MAIN ENDP
215 ;
216 ; Send file contents to remote.
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-5
217 ;
218 0139 SEND PROC NEAR
219 0139 C6 06 09ED R 00 MOV BYTE PTR [TRIES],0 ; Conditional for Read
220 013E E8 04A9 R CALL SET_INT ; Set up interrupts
221 0141 BE 0C5C R MOV SI,OFFSET PRP7 ; Point to 'Sending'
222 0144 E8 03D9 R CALL PROMPT ; Print to screen
223 0147 E8 059E R CALL OPEN_R ; Open for read
224 014A 72 64 JC EXITF ; Can't open the file
225 014C BE 0CFA R MOV SI,OFFSET FNAME ; Point to filename
226 014F E8 03D9 R CALL PROMPT ; Print to screen
227 0152 BE 0C28 R MOV SI,OFFSET CRLF ; End of the line
228 0155 E8 03D9 R CALL PROMPT ; Print to screen
229 0158 E8 062E R CALL READ ; Read the file first
230 015B E8 0397 R CALL TXSYNCH ; Synchronize
231 015E 72 50 JC EXITF ; Abort
232 0160 E8 08FE R CALL SAV_SCR
233 0163 E8 0970 R CALL WRT_SCR
234 0166 EB 06 JMP SHORT BYPASS ; Bypass first read (already done)
235 0168 E8 07FC R SEND0: CALL SHOW ; Show what we are doing
236 016B E8 062E R CALL READ ; Read the file
237 016E C6 06 09ED R 0A BYPASS: MOV BYTE PTR [TRIES],MAX ; Max attempts to send blocks
238 0173 E8 0277 R SEND1: CALL SDATA ; Send the data
239 ;
240 0176 E8 031C R SEND2: CALL GET_ACK ; Get host ackknowlege
241 0179 72 35 JC EXITF ; Fatal exit
242 017B 75 20 JNZ CHKRES ; Was not good
243 017D B0 20 MOV AL,' ' ; Clear any error mes
244 017F E8 03CD R CALL SHO_RES ; on the screen
245 0182 80 3E 09E7 R 00 CMP BYTE PTR [FEND],0 ; Check for file end
246 0187 74 DF JZ SEND0 ; Not end of the file yet
247 0189 E8 093B R CALL RES_SCR ; Restore the screen.
248 ;
249 018C BE 0C97 R MOV SI,OFFSET PRP10 ; Point to the prompt
250 018F E8 03D9 R CALL PROMPT
251 0192 E8 0624 R CALL CLOSE ; Close the file
252 0195 E8 054A R CALL RES_INT ; Restore vectors
253 0198 B8 4C00 MOV AX,4C00H ; Exit with NO errors
254 019B CD 21 INT MS_DOS ; Do it now
255 ;
256 019D 3C 18 CHKRES: CMP AL,CAN ; Wanted to cancel?
257 019F 74 0F JZ EXITF ; Yes
258 01A1 3C 15 CMP AL,NAK ; Is it a NAK?
259 01A3 75 D1 JNZ SEND2 ; No, must be garbage, try again.
260 01A5 B0 2A MOV AL,'*' ; Was a NAK.
261 01A7 E8 03CD R CALL SHO_RES ; Show error response
262 01AA FE 0E 09ED R DEC BYTE PTR [TRIES] ; Bump retries
263 01AE 75 C3 JNZ SEND1 ; Continue
264 ;
265 01B0 BC 0E80 R EXITF: MOV SP,OFFSET STACKP ; Level stack
266 01B3 E8 08F3 R CALL SENDX ; Tell other end to quit
267 01B6 E8 093B R CALL RES_SCR ; Restore screen state
268 01B9 BE 0C7E R MOV SI,OFFSET PRP9 ; Point to 'aborted'
269 01BC E8 03D9 R CALL PROMPT ; Print to screen
270 01BF E8 0624 R CALL CLOSE ; Close the file
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-6
271 01C2 E8 054A R CALL RES_INT ; Restore interrupts
272 01C5 B8 4C01 MOV AX,4C01H ; Exit with error
273 01C8 CD 21 INT MS_DOS ; Do it now
274 01CA SEND ENDP
275 ;
276 ; Receive a file from remote
277 ;
278 01CA RECV PROC NEAR
279 01CA E8 04A9 R CALL SET_INT ; Set up interrupts
280 01CD BE 0C6C R MOV SI,OFFSET PRP8 ; Point to 'receiving'
281 01D0 E8 03D9 R CALL PROMPT ; Print to screen
282 01D3 E8 05C1 R CALL OPEN_W ; Open for write
283 01D6 72 33 JC CANCEL ; Bad open
284 01D8 BE 0CFA R MOV SI,OFFSET FNAME ; Point to filename
285 01DB E8 03D9 R CALL PROMPT ; Print to screen
286 01DE BE 0C28 R MOV SI,OFFSET CRLF
287 01E1 E8 03D9 R CALL PROMPT
288 01E4 E8 0397 R CALL RXSYNCH ; Establish communications
289 01E7 72 22 JC CANCEL ; No good, quit.
290 01E9 E8 08FE R CALL SAV_SCR ; Save screen context
291 01EC E8 0970 R CALL WRT_SCR ; Write box on screen
292 01EF C6 06 09ED R 0A MOV BYTE PTR [TRIES],MAX ; Max re-tries
293 01F4 EB 0A JMP SHORT NONAK ; Bypass the initial NAK
294 01F6 B0 2A RECV0: MOV AL,'*'
295 01F8 E8 03CD R CALL SHO_RES ; Show response
296 01FB B0 15 MOV AL,NAK ; Get a NAK
297 01FD E8 02A3 R RECV1: CALL RESP ; Send to remote
298 0200 E8 0350 R NONAK: CALL RDATA ; Receive data
299 0203 73 20 JNC RECV3 ; Good block
300 0205 FE 0E 09ED R RECV2: DEC BYTE PTR [TRIES] ; Bump retries
301 0209 75 EB JNZ RECV0 ; Send a NAK and try again
302 ;
303 020B BC 0E80 R CANCEL: MOV SP,OFFSET STACKP ; Level stack
304 020E E8 08F3 R CALL SENDX ; Tell remote to quit
305 0211 E8 093B R CALL RES_SCR ; Restore screen context
306 0214 BE 0C7E R MOV SI,OFFSET PRP9 ; Point to 'aborted'
307 0217 E8 03D9 R CALL PROMPT ; Print to screen
308 021A E8 0624 R CALL CLOSE ; Close the file
309 021D E8 054A R CALL RES_INT ; Restore interrupts
310 0220 B8 4C01 MOV AX,4C01H ; Exit with error
311 0223 CD 21 INT MS_DOS ; Exit now
312 ;
313 0225 E8 044E R RECV3: CALL CRC ; Check the CRC
314 0228 75 DB JNZ RECV2 ; Bad CRC
315 022A B0 06 MOV AL,ACK ; Get an ACK
316 022C E8 02A3 R CALL RESP ; Send to remote
317 022F B0 20 MOV AL,' '
318 0231 E8 03CD R CALL SHO_RES ; Show good response
319 0234 E8 06C4 R CALL WRITE ; Write the file
320 0237 72 D2 JC CANCEL ; Write past end of disk!
321 0239 1E PUSH DS ; Save segment
322 023A 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Get buffer segment
323 023E A0 0002 MOV AL,BYTE PTR DS:[CTRL] ; Get control byte
324 0241 1F POP DS ; Restore segment
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-7
325 0242 A8 04 TEST AL,EOF ; Check for end-of-file
326 0244 75 0B JNZ END_F ; Is end of file
327 0246 A8 20 TEST AL,ABORT ; Check for abort
328 0248 75 C1 JNZ CANCEL ; It was an abort
329 024A C6 06 09ED R 0A MOV BYTE PTR [TRIES],MAX ; Reset the retry count
330 024F EB AF JMP SHORT NONAK ; Get more
331 ;
332 0251 BC 0E80 R END_F: MOV SP,OFFSET STACKP ; Level stack
333 0254 B0 20 MOV AL,' '
334 0256 E8 03CD R CALL SHO_RES ; Show response
335 0259 B9 0005 MOV CX,5 ; Number of ACKs
336 025C B0 06 ENDACK: MOV AL,ACK ; Get an ack
337 025E E8 02A3 R CALL RESP ; Send to remote
338 0261 E2 F9 LOOP ENDACK ; Send a few.
339 0263 E8 093B R CALL RES_SCR ; Restore screen context
340 0266 BE 0C97 R MOV SI,OFFSET PRP10 ; Point to 'good'
341 0269 E8 03D9 R CALL PROMPT ; Print to screen
342 026C E8 0624 R CALL CLOSE ; Close the file
343 026F E8 054A R CALL RES_INT ; Restore vectors
344 0272 B8 4C00 MOV AX,4C00H ; Exit with NO errors
345 0275 CD 21 INT MS_DOS
346 0277 RECV ENDP
347 ;
348 ; Send data. Data is in the BUFFER.IDATA
349 ;
350 0277 SDATA PROC NEAR
351 0277 8B 16 0A10 R MOV DX,WORD PTR [PORT] ; Get port address
352 027B A0 09E9 R MOV AL,BYTE PTR [REC_NOL] ; Get low byte of rec to xmit.
353 027E 1E PUSH DS ; Save segment
354 027F 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Pick up data buffer
355 0283 8B 0E 0000 MOV CX,WORD PTR DS:[LEN] ; Get the string length
356 0287 A2 0003 MOV BYTE PTR DS:[RECN],AL ; Record number
357 028A E8 044E R CALL CRC ; Calculate the CRC
358 028D 33 F6 XOR SI,SI ; Offset Zero
359 028F 83 C2 05 SDATA1: ADD DX,5 ; Offset to status
360 0292 EC SDATA2: IN AL,DX ; Get UART status
361 0293 A8 20 TEST AL,THRE ; Test holding register ready
362 0295 74 FB JZ SDATA2 ; Wait
363 0297 E8 03E8 R CALL FLOW ; Flow control
364 029A 83 EA 05 SUB DX,5 ; To base port
365 029D AC LODSB ; Get memory byte
366 029E EE OUT DX,AL ; Output to UART
367 029F E2 EE LOOP SDATA1 ; Continue for all bytes
368 02A1 1F POP DS ; Restore data segment
369 02A2 C3 RET ; Exit
370 02A3 SDATA ENDP
371 ;
372 ; Send a single byte in AL to the modem port.
373 ;
374 02A3 RESP PROC NEAR
375 02A3 E8 03E8 R CALL FLOW ; Flow control
376 02A6 FORCE PROC NEAR ; Force output, no flow control
377 02A6 52 PUSH DX ; Save
378 02A7 50 PUSH AX ; Save byte
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-8
379 02A8 2E: 8B 16 0A10 R MOV DX,WORD PTR CS:[PORT] ; Get modem port
380 02AD 83 C2 05 ADD DX,5 ; Offset to status
381 02B0 EC RESP0: IN AL,DX ; Get the status
382 02B1 24 20 AND AL,THRE ; Test holding register ready
383 02B3 74 FB JZ RESP0 ; Wait
384 02B5 83 EA 05 SUB DX,5 ; To base port
385 02B8 58 POP AX ; Restore byte to send
386 02B9 EE OUT DX,AL ; Output to UART
387 02BA 5A POP DX ; Restore
388 02BB C3 RET
389 02BC FORCE ENDP
390 02BC RESP ENDP
391 ;
392 ; Easy interrupt happens each time a byte is assembled in the UART.
393 ; The byte is stacked in the interrupt buffer and the time-out clock
394 ; is reset. An appropriate reset is also sent to the interrupt
395 ; controller.
396 ;
397 02BC EASY_INT PROC FAR
398 02BC 50 PUSH AX ; Save registers used.
399 02BD 53 PUSH BX
400 02BE 52 PUSH DX
401 02BF 1E PUSH DS
402 ;
403 02C0 0E PUSH CS
404 02C1 1F POP DS ; DS=CS
405 ;
406 02C2 8B 16 0A10 R MOV DX,WORD PTR [PORT] ; Get port address
407 02C6 83 C2 02 ADD DX,2 ; Offset to interrupt ident regis.
408 02C9 EC IN AL,DX ; Get mask
409 02CA 24 07 AND AL,00000111B ; Mask all but lower 3 bits
410 02CC A8 01 TEST AL,00000001B ; Check for interrupt pending
411 02CE 75 29 JNZ INT_EX ; No interupts pending
412 02D0 A8 04 TEST AL,RDAT ; See if data pending
413 02D2 75 09 JNZ INT_DAT ; Yes, get it
414 02D4 83 C2 04 ADD DX,4 ; Offset to modem status
415 02D7 EC IN AL,DX ; Get modem status
416 02D8 A2 09E8 R MOV BYTE PTR [MOD_STA],AL ; Save in CS
417 02DB EB 1C JMP SHORT INT_EX ; Leave
418 02DD INT_DAT:
419 02DD 83 EA 02 SUB DX,2 ; Back to base port
420 02E0 EC IN AL,DX ; Get the byte
421 02E1 8B 1E 0A0A R MOV BX,WORD PTR [WPOINT] ; Pick up write pointer
422 02E5 FF 06 0A0A R INC WORD PTR [WPOINT] ; Ready next
423 02E9 FF 06 0A08 R INC WORD PTR [BYTE_CNT] ; Count of bytes in the buffer
424 02ED C7 06 09EF R 0012 MOV WORD PTR [CLOCK],TIMOUT ; Set timeout to max again
425 02F3 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Pick up buffer segment
426 02F7 88 07 MOV BYTE PTR [BX],AL ; Put byte in the buffer
427 02F9 B0 20 INT_EX: MOV AL,20H ; Non-specific end-of-interrupt
428 02FB E6 20 OUT 20H,AL ; Reset the controller
429 ;
430 02FD 1F POP DS ; Restore registers used
431 02FE 5A POP DX
432 02FF 5B POP BX
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-9
433 0300 58 POP AX
434 0301 CF IRET
435 0302 EASY_INT ENDP
436 ;
437 ; Return byte count in interrupt buffer in CX.
438 ;
439 0302 CHK_STA PROC NEAR
440 0302 FA CLI ; No interrupts
441 0303 2E: 8B 0E 0A08 R MOV CX,WORD PTR CS:[BYTE_CNT] ; Get byte count
442 0308 0B C9 OR CX,CX ; Test for zero
443 030A 75 0E JNZ CHK_EX ; Got some bytes
444 030C CLR_BUF PROC NEAR
445 030C 2E: C7 06 0A0A R 8000 MOV WORD PTR CS:[WPOINT],HOME ; Set pointer to top of buffer
446 0313 2E: C7 06 0A08 R 0000 MOV WORD PTR CS:[BYTE_CNT],0 ; Zero the byte-count
447 031A FB CHK_EX: STI ; Allow interrupts
448 031B C3 RET
449 031C CLR_BUF ENDP
450 031C CHK_STA ENDP
451 ;
452 ; Get a single byte from the remote. Check to see if its an ACK.
453 ;
454 031C GET_ACK PROC NEAR
455 031C C7 06 09EF R 00FF MOV WORD PTR [CLOCK],255 ; Max time to wait
456 0322 GET_INP PROC NEAR
457 0322 51 PUSH CX ; Save count
458 0323 83 3E 09EF R 00 GET0: CMP WORD PTR [CLOCK],0 ; Check for timeout
459 0328 74 17 JZ GET1
460 032A E8 0302 R CALL CHK_STA ; Check status
461 032D 74 F4 JZ GET0 ; No bytes available
462 ;
463 032F FA CLI ; CLR_BUF enables
464 0330 E8 030C R CALL CLR_BUF ; Clear any garbage.
465 0333 1E PUSH DS
466 0334 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Pick up buffer segment
467 0338 A0 8000 MOV AL,BYTE PTR DS:[HOME] ; Pick up byte at bottom
468 033B 1F POP DS
469 033C 3C 06 CMP AL,ACK ; Check for an ACK
470 033E F8 CLC ; Clear carry
471 033F EB 01 JMP SHORT GET2 ; Exit
472 ;
473 0341 F9 GET1: STC ; Set carry for error
474 0342 59 GET2: POP CX ; Restore count
475 0343 C3 RET
476 0344 GET_INP ENDP
477 0344 GET_ACK ENDP
478 ;
479 ; Eat any incoming bytes.
480 ;
481 0344 EAT PROC NEAR
482 0344 C7 06 09EF R 0012 MOV WORD PTR [CLOCK],TIMOUT ; Maximum time to wait
483 034A E8 0322 R EAT0: CALL GET_INP ; Get any trash
484 034D 73 FB JNC EAT0 ; Continue until nothing available
485 034F C3 RET
486 0350 EAT ENDP
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-10
487 ;
488 ; Receive data string from remote. First word is the string length.
489 ;
490 0350 RDATA PROC NEAR
491 0350 C7 06 09EF R 00FF MOV WORD PTR [CLOCK],255 ; Max time to wait
492 ;
493 ; Wait for the first two bytes so we know how many bytes are supposed
494 ; to be received.
495 ;
496 0356 83 3E 09EF R 00 RDATA0: CMP WORD PTR [CLOCK],0 ; Check for timeout
497 035B 74 38 JZ RDATA2 ; Timed out
498 035D E8 0302 R CALL CHK_STA ; Check status
499 0360 83 F9 02 CMP CX,2 ; Check for two bytes received
500 0363 72 F1 JC RDATA0 ; Not here yet
501 0365 1E PUSH DS
502 0366 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Pick up buffer segment
503 036A A1 8000 MOV AX,WORD PTR DS:[HOME] ; Pick up word at bottom
504 036D 1F POP DS
505 ;
506 ; AX now contains the string length. Wait until the entire string is
507 ; received by checking the status.
508 ;
509 036E 83 3E 09EF R 00 RDATA1: CMP WORD PTR [CLOCK],0 ; Check for timeout
510 0373 74 20 JZ RDATA2 ; Timed out
511 0375 E8 0302 R CALL CHK_STA ; Check status
512 0378 3B C8 CMP CX,AX ; Check byte count
513 037A 72 F2 JC RDATA1 ; Not here yet
514 ;
515 ; Got all the bytes we need, now transfer them.
516 ;
517 037C 1E PUSH DS
518 037D 06 PUSH ES
519 037E A1 09F3 R MOV AX,WORD PTR [BUF_SEG] ; Pick up segment
520 0381 8E C0 MOV ES,AX
521 0383 8E D8 MOV DS,AX ; Fix up segments
522 0385 BE 8000 MOV SI,HOME ; Where data is
523 0388 BF 0000 MOV DI,LEN ; Where to put it
524 038B F3/ A4 REP MOVSB ; transfer it
525 038D 07 POP ES ; Restore registers
526 038E 1F POP DS
527 038F FA CLI ; CLR_BUF enables
528 0390 E8 030C R CALL CLR_BUF ; Clear the buffer
529 0393 F8 CLC ; Show no errors
530 0394 C3 RET
531 ;
532 ; Timeout error return
533 ;
534 0395 F9 RDATA2: STC
535 0396 C3 RET
536 0397 RDATA ENDP
537 ;
538 ; Attempt to synchronize TX/RX
539 ;
540 0397 TXSYNCH PROC NEAR ;
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-11
541 0397 RXSYNCH PROC NEAR
542 0397 BE 0CDF R MOV SI,OFFSET PRP13 ; Pick up prompt
543 039A E8 03D9 R CALL PROMPT ; Print to console
544 039D FA CLI ; CLR_BUF enables
545 039E E8 030C R CALL CLR_BUF ; Clear any garbage
546 03A1 C7 06 09EF R 0200 MOV WORD PTR [CLOCK],512 ; Max time to wait
547 03A7 B9 0040 MOV CX,64 ; Bytes to TX/RX
548 ; Bytes to get
549 03AA B0 16 RXSYN0: MOV AL,SYN ; Send a SYN byte
550 03AC E8 02A3 R CALL RESP ; Send to remote
551 03AF E8 0322 R CALL GET_INP ; Get a byte
552 03B2 72 17 JC RXSYN2 ; Exit fatal
553 03B4 3C 18 CMP AL,CAN ; Was it a ^X?
554 03B6 74 13 JZ RXSYN2 ; Yes, Exit fatal
555 03B8 3C 16 CMP AL,SYN ; Get SYNC character?
556 03BA 75 EE JNZ RXSYN0 ; No, wait some more
557 03BC E2 EC LOOP RXSYN0 ; Continue for all bytes
558 03BE BE 0CC9 R MOV SI,OFFSET PRP12 ; Pick up prompt
559 03C1 E8 03D9 R CALL PROMPT ; Print to console
560 03C4 B0 16 MOV AL,SYN ; Send a SYN byte
561 03C6 E8 02A3 R CALL RESP ; Send to remote
562 03C9 F8 CLC
563 03CA C3 RET
564 03CB F9 RXSYN2: STC ; Abort
565 03CC C3 RET
566 03CD RXSYNCH ENDP
567 03CD TXSYNCH ENDP
568 ;
569 ; Show ACK/NAK with a '*' after the block
570 ;
571 03CD SHO_RES PROC NEAR
572 03CD 1E PUSH DS ; Save screen segment
573 03CE 8E 1E 0A0E R MOV DS,WORD PTR [SCR_SEG] ; Pick up screen segment
574 03D2 B4 70 MOV AH,SCRATTR ; Normal attribute
575 03D4 A3 055E MOV WORD PTR DS:[SCR_ACK],AX ; Put on the screen
576 03D7 1F POP DS
577 03D8 C3 RET
578 03D9 SHO_RES ENDP
579 ;
580 ; Print string to console until a NULL. String location in SI
581 ;
582 03D9 PROMPT PROC NEAR
583 03D9 AC LODSB ; Get byte
584 03DA 0A C0 OR AL,AL ; Check for a null
585 03DC 74 09 JZ PREXT ; End of the string
586 03DE B4 0E MOV AH,14 ; 'Dumb' terminal mode
587 03E0 BB 0007 MOV BX,0007H ; Normal attribute
588 03E3 CD 10 INT VIDEO ; Print character
589 03E5 EB F2 JMP SHORT PROMPT ; Continue
590 03E7 C3 PREXT: RET
591 03E8 PROMPT ENDP
592 ;
593 ; Flow control and carrier detect.
594 ;
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-12
595 03E8 FLOW PROC NEAR
596 03E8 50 PUSH AX ; Save byte
597 03E9 51 PUSH CX ; Save any count
598 03EA 1E PUSH DS ; Save data segment
599 03EB 0E PUSH CS
600 03EC 1F POP DS ; DS=CS
601 03ED 80 3E 09E4 R 00 CMP BYTE PTR [ENABLE],0 ; Original mask
602 03F2 74 56 JZ CONT1 ; Ignore flow control
603 03F4 80 3E 09DD R 00 FLOW0: CMP BYTE PTR [KILL],0 ; Check for an abort
604 03F9 75 14 JNZ BYEBYE ; Wanted to abort
605 03FB A0 09E8 R MOV AL,BYTE PTR [MOD_STA] ; Get modem status
606 03FE A8 80 TEST AL,RLSD ; Check for carrier
607 0400 75 27 JNZ CAROK ; Carrier is still okay
608 0402 80 3E 09E5 R 00 CMP BYTE PTR [WASC],0 ; See if a carrier when we started
609 0407 74 20 JZ CAROK ; No, ignore status
610 0409 BE 0CB1 R MOV SI,OFFSET PRP11 ; Point to carrier failed
611 040C E8 03D9 R CALL PROMPT
612 040F BC 0E80 R BYEBYE: MOV SP,OFFSET STACKP ; Level stack
613 0412 E8 0624 R CALL CLOSE ; Close the file
614 0415 E8 08F3 R CALL SENDX ; Tell other end to quit.
615 0418 E8 093B R CALL RES_SCR ; Restore screen
616 041B BE 0C7E R MOV SI,OFFSET PRP9 ; Point to aborted
617 041E E8 03D9 R CALL PROMPT ; Print to screen
618 0421 E8 054A R CALL RES_INT ; Restore interrupts
619 0424 B8 4C01 MOV AX,4C01H ; Error exit
620 0427 CD 21 INT MS_DOS ; Exit
621 ;
622 0429 24 30 CAROK: AND AL,CTSDSR ; Mask all but DSR/CTS
623 042B 3A 06 09E4 R CMP AL,BYTE PTR [ENABLE] ; Original mask
624 042F 74 02 JZ CONT0 ; Okay to continue
625 0431 EB C1 JMP SHORT FLOW0 ; Wait until Okay
626 ;
627 0433 E8 0302 R CONT0: CALL CHK_STA ; Check for any incomming bytes
628 0436 74 12 JZ CONT1 ; Buffer's clear
629 0438 1E PUSH DS ; Save segment
630 0439 2E: 8E 1E 09F3 R MOV DS,WORD PTR CS:[BUF_SEG] ; Pick up segment
631 043E A0 8000 MOV AL,BYTE PTR DS:[HOME] ; Get byte in the buffer
632 0441 1F POP DS ; Restore segment
633 0442 3C 18 CMP AL,CAN ; Want to cancel?
634 0444 74 C9 JZ BYEBYE ; Yes
635 0446 FA CLI ; CLR_BUF Restores
636 0447 E8 030C R CALL CLR_BUF ; Clear the buffer
637 ;
638 044A 1F CONT1: POP DS ; Restore segment
639 044B 59 POP CX ; Restore any count
640 044C 58 POP AX ; Restore byte
641 044D C3 RET
642 044E FLOW ENDP
643 ;
644 ; Make/check CRC word. String is in BUFFER
645 ;
646 044E CRC PROC NEAR
647 044E 51 PUSH CX
648 044F 56 PUSH SI
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-13
649 0450 1E PUSH DS
650 0451 2E: 8E 1E 09F3 R MOV DS,WORD PTR CS:[BUF_SEG] ; Pick up buffer segment
651 0456 8B 0E 0000 MOV CX,WORD PTR DS:[LEN] ; Get string length
652 045A 83 E9 02 SUB CX,2 ; Don't CRC the CRC
653 045D 32 E4 XOR AH,AH ; Always zero
654 045F 33 DB XOR BX,BX ; Start with zero
655 0461 33 F6 XOR SI,SI ; Buffer offset zero
656 0463 51 CRC0: PUSH CX ; Save count
657 0464 AC LODSB ; Get byte
658 0465 03 D8 ADD BX,AX ; Total so far
659 0467 83 E1 07 AND CX,0000111B ; Rotate max 7 bits
660 046A D3 C3 ROL BX,CL ; Multiply
661 046C 59 POP CX ; Restore count
662 046D E2 F4 LOOP CRC0 ; Continue
663 046F 39 1C CMP WORD PTR [SI],BX ; For checking
664 0471 89 1C MOV WORD PTR [SI],BX ; Insert CRC
665 0473 1F POP DS
666 0474 5E POP SI
667 0475 59 POP CX
668 0476 C3 RET
669 0477 CRC ENDP
670 ;
671 0477 SET_SEG PROC NEAR
672 0477 B8 0E90 R MOV AX,OFFSET BUFFER ; Point to buffer
673 047A D1 E8 SHR AX,1 ; /2
674 047C D1 E8 SHR AX,1 ; /4
675 047E D1 E8 SHR AX,1 ; /8
676 0480 D1 E8 SHR AX,1 ; /16
677 0482 8C CB MOV BX,CS ; Get code segment
678 0484 03 C3 ADD AX,BX ; Add to offset paragraph
679 0486 A3 09F3 R MOV WORD PTR [BUF_SEG],AX ; Save for later
680 0489 05 1000 ADD AX,4096 ; Next segment higher
681 048C A3 09F5 R MOV WORD PTR [DAT_SEG],AX ; Into next
682 048F C3 RET
683 0490 SET_SEG ENDP
684 ;
685 ; Local extension of the clock vector.
686 ;
687 0490 LCL_CLK PROC FAR
688 0490 FB STI ; Allow interrupts
689 0491 50 PUSH AX ; Save registers used
690 0492 B0 20 MOV AL,20H ; Non-specific end-of-interrupt
691 0494 E6 20 OUT 20H,AL ; Out to the controller
692 0496 58 POP AX ; Restore registers used
693 0497 2E: 83 3E 09EF R 00 CMP WORD PTR CS:[CLOCK],0 ; See if already zero
694 049D 74 05 JZ CLK_EX ; Yes, quit
695 049F 2E: FF 0E 09EF R DEC WORD PTR CS:[CLOCK] ; Bump the timer
696 04A4 2E: FF 2E 09F7 R CLK_EX: JMP DWORD PTR CS:[OLD_CLK] ; Continue
697 04A9 LCL_CLK ENDP
698 ;
699 04A9 SET_INT PROC NEAR
700 04A9 C6 06 09DF R FF MOV BYTE PTR [INT_FLG],0FFH ; Show we've set up interrupts
701 04AE E8 030C R CALL CLR_BUF ; Put pointers at correct loc
702 04B1 8B 16 0A10 R MOV DX,WORD PTR [PORT] ; Get port address
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-14
703 04B5 83 C2 01 ADD DX,1 ; Interrupt enable register
704 04B8 EC IN AL,DX ; Get the control byte
705 04B9 A2 09E6 R MOV BYTE PTR [STATUS],AL ; Save interrupt status
706 04BC B0 09 MOV AL,(INT_RC OR INT_MS) ; Interrupt on rec. chr. / mod. sta.
707 04BE EE OUT DX,AL ; Enable interrupts
708 ;
709 04BF 83 C2 03 ADD DX,3 ; Offset to modem control register
710 04C2 B0 0B MOV AL,RTS_DTR OR TRISTAT ; Get control byte
711 04C4 EE OUT DX,AL ; Output the byte
712 04C5 83 C2 02 ADD DX,2 ; Offset to modem status
713 04C8 EC IN AL,DX ; Get modem status
714 04C9 A2 09E8 R MOV BYTE PTR [MOD_STA],AL ; Save the modem status
715 04CC 8A E0 MOV AH,AL ; Duplicate
716 04CE 80 E4 80 AND AH,RLSD ; Mask all but carrier det
717 04D1 88 26 09E5 R MOV BYTE PTR [WASC],AH ; Save carrier status
718 04D5 24 30 AND AL,CTSDSR ; Mask all but CTS/DSR
719 04D7 A2 09E4 R MOV BYTE PTR [ENABLE],AL ; Save data enable byte
720 ;
721 04DA 06 PUSH ES ; Save segment
722 04DB A0 0A12 R MOV AL,BYTE PTR [COM_INT] ; COM interrupt
723 04DE B4 35 MOV AH,35H ; Get interrupt vector
724 04E0 CD 21 INT MS_DOS ; Go get it
725 04E2 8C 06 0A05 R MOV WORD PTR [UAR_SEG],ES ; Store UART segment
726 04E6 89 1E 0A03 R MOV WORD PTR [UAR_OFF],BX ; Store UART offset
727 ;
728 04EA B0 1C MOV AL,1CH ; Clock interrupt
729 04EC B4 35 MOV AH,35H ; Get interrupt vector
730 04EE CD 21 INT MS_DOS ; Go get it
731 04F0 8C 06 09F9 R MOV WORD PTR [CLK_SEG],ES ; Store clock segment
732 04F4 89 1E 09F7 R MOV WORD PTR [CLK_OFF],BX ; Store clock offset
733 ;
734 04F8 B0 1B MOV AL,1BH ; Control break interrupt
735 04FA B4 35 MOV AH,35H ; Get interrupt vector
736 04FC CD 21 INT MS_DOS ; Go get it
737 04FE 8C 06 09FD R MOV WORD PTR [BRK_SEG],ES ; Store clock segment
738 0502 89 1E 09FB R MOV WORD PTR [BRK_OFF],BX ; Store clock offset
739 ;
740 0506 B0 23 MOV AL,23H ; Control C interrupt
741 0508 B4 35 MOV AH,35H ; Get interrupt vector
742 050A CD 21 INT MS_DOS ; Go get it
743 050C 8C 06 0A01 R MOV WORD PTR [CTC_SEG],ES ; Store clock segment
744 0510 89 1E 09FF R MOV WORD PTR [CTC_OFF],BX ; Store clock offset
745 0514 07 POP ES ; Restore segment
746 ;
747 0515 A0 0A12 R MOV AL,BYTE PTR [COM_INT] ; Communications vector
748 0518 B4 25 MOV AH,25H ; Set interrupt vector
749 051A BA 02BC R MOV DX,OFFSET EASY_INT ; Our local vector
750 051D CD 21 INT MS_DOS ; Go set it
751 ;
752 051F E4 21 IN AL,INT_CTL ; Get interrupt control mask
753 0521 A2 0A07 R MOV BYTE PTR [OLD_MASK],AL ; Save the mask.
754 0524 22 06 0A13 R AND AL,BYTE PTR [COM_MSK] ; Set the mask
755 0528 E6 21 OUT INT_CTL,AL ; Set the mask
756 ;
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-15
757 052A B0 1C MOV AL,1CH ; Clock vector
758 052C B4 25 MOV AH,25H ; Set interrupt vector
759 052E BA 0490 R MOV DX,OFFSET LCL_CLK ; Our local vector
760 0531 CD 21 INT MS_DOS ; Go set it
761 ;
762 0533 B0 1B MOV AL,1BH ; Control break vector
763 0535 B4 25 MOV AH,25H ; Set interrupt vector
764 0537 BA 07F5 R MOV DX,OFFSET BRK ; Our local vector
765 053A CD 21 INT MS_DOS ; Go set it
766 ;
767 053C B0 23 MOV AL,23H ; Control C vector
768 053E B4 25 MOV AH,25H ; Set interrupt vector
769 0540 BA 07F5 R MOV DX,OFFSET BRK ; Our local vector
770 0543 CD 21 INT MS_DOS ; Go set it
771 0545 B0 20 MOV AL,20H ; Non-specific end-of-interrupt
772 0547 E6 20 OUT 20H,AL ; Reset controller
773 0549 C3 RET
774 054A SET_INT ENDP
775 ;
776 054A RES_INT PROC NEAR
777 054A 80 3E 09DF R 00 CMP BYTE PTR [INT_FLG],0 ; See if we have hot Interrupts
778 054F 75 01 JNZ HOT_IN ; Yes
779 0551 C3 RET ; No, don't "restore" them
780 0552 E8 0344 R HOT_IN: CALL EAT ; Clear receive buffer.
781 0555 C6 06 09DF R 00 MOV BYTE PTR [INT_FLG],0 ; Show we are doing it now
782 055A 8B 16 0A10 R MOV DX,WORD PTR [PORT] ; Get port address
783 055E 83 C2 01 ADD DX,1 ; Interrupt enable register
784 0561 A0 09E6 R MOV AL,BYTE PTR [STATUS] ; Get old UART status
785 0564 EE OUT DX,AL ; Restore it
786 ;
787 0565 A0 0A07 R MOV AL,BYTE PTR [OLD_MASK] ; Get old Interrupt/ctl mask
788 0568 E6 21 OUT INT_CTL,AL ; Restore it
789 ;
790 056A 1E PUSH DS ; Save segment
791 056B A0 0A12 R MOV AL,BYTE PTR [COM_INT] ; Vector to restore
792 056E B4 25 MOV AH,25H ; Set interrupt function
793 0570 2E: C5 16 0A03 R LDS DX,CS:[OLD_UART] ; Pick up old vector
794 0575 CD 21 INT MS_DOS ; Restore it
795 ;
796 0577 B0 1C MOV AL,1CH ; Vector to restore
797 0579 B4 25 MOV AH,25H ; Set interrupt function
798 057B 2E: C5 16 09F7 R LDS DX,CS:[OLD_CLK] ; Pick up old vector
799 0580 CD 21 INT MS_DOS ; Restore it
800 ;
801 0582 B4 25 MOV AH,25H ; Set interrupt function
802 0584 B0 1B MOV AL,1BH ; Control break vector
803 0586 2E: C5 16 09FB R LDS DX,CS:[OLD_BRK] ; Pick up old vector
804 058B CD 21 INT MS_DOS ; Restore it
805 ;
806 058D B4 25 MOV AH,25H ; Set interrupt function
807 058F B0 23 MOV AL,23H ; Control C vector
808 0591 2E: C5 16 09FF R LDS DX,CS:[OLD_CTC] ; Pick up old vector
809 0596 CD 21 INT MS_DOS ; Restore it
810 0598 1F POP DS
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-16
811 0599 B0 20 MOV AL,20H ; Non-specific end-of-interrupt
812 059B E6 20 OUT 20H,AL ; Reset controller
813 059D C3 RET
814 059E RES_INT ENDP
815 ;
816 ; Open a fiile for reading.
817 ;
818 059E OPEN_R PROC NEAR
819 059E B8 3D00 MOV AX,3D00H ; Open for read
820 05A1 33 C9 XOR CX,CX ; Normal file
821 05A3 BA 0CFA R MOV DX,OFFSET FNAME ; File name
822 05A6 CD 21 INT MS_DOS
823 05A8 A3 09F1 R MOV WORD PTR [HANDLE],AX ; Save handle/error code
824 05AB 73 13 JNC OPN_OK
825 05AD BE 0C2B R MOV SI,OFFSET PRP4 ; Point to prompt
826 05B0 E8 03D9 R CALL PROMPT ; Print to screen
827 05B3 BE 0CFA R MOV SI,OFFSET FNAME ; Point to filename
828 05B6 E8 03D9 R CALL PROMPT ; Print to screen
829 05B9 BE 0C3D R MOV SI,OFFSET PRP5 ; End of the string
830 05BC E8 03D9 R CALL PROMPT
831 05BF F9 STC ; Maintain error status
832 05C0 C3 OPN_OK: RET
833 05C1 OPEN_R ENDP
834 ;
835 05C1 OPEN_W PROC NEAR
836 05C1 B8 3D00 MOV AX,3D00H ; Open for read
837 05C4 33 C9 XOR CX,CX ; Normal file
838 05C6 BA 0CFA R MOV DX,OFFSET FNAME ; File name
839 05C9 CD 21 INT MS_DOS
840 05CB A3 09F1 R MOV WORD PTR [HANDLE],AX ; Save handle/error code
841 05CE 72 31 JC CREATE ; Not found, create one.
842 05D0 E8 0624 R CALL CLOSE ; File was found, close it
843 05D3 BE 0CFA R MOV SI,OFFSET FNAME ; Present file name
844 05D6 BF 0D3A R MOV DI,OFFSET ONAME ; New name to '.old'
845 05D9 B9 0040 MOV CX,64 ; Max characters
846 05DC AC NFILE0: LODSB ; Get byte
847 05DD 3C 2E CMP AL,'.' ; Find the delimiter?
848 05DF 75 0A JNZ NODOT
849 05E1 AA STOSB ; Put in the dot
850 05E2 B0 4F MOV AL,'O' ; Get a 'O' for old
851 05E4 AA STOSB ; Save
852 05E5 B8 444C MOV AX,'DL' ; 'LD' backwards
853 05E8 AB STOSW ; Save in string
854 05E9 EB 03 JMP SHORT NFILE1
855 05EB AA NODOT: STOSB
856 05EC E2 EE LOOP NFILE0 ; Continue for the whole name
857 05EE B8 4100 NFILE1: MOV AX,4100H ; Delete file function
858 05F1 BA 0D3A R MOV DX,OFFSET ONAME ; Delete any such old name
859 05F4 CD 21 INT MS_DOS ; Do it, ignore any errors
860 05F6 B8 5600 MOV AX,5600H ; Rename file
861 05F9 BA 0CFA R MOV DX,OFFSET FNAME ; File to be renamed
862 05FC BF 0D3A R MOV DI,OFFSET ONAME ; What to name it to
863 05FF CD 21 INT MS_DOS ; Rename the file
864 0601 B8 3C00 CREATE: MOV AX,3C00H ; Create file
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-17
865 0604 BA 0CFA R MOV DX,OFFSET FNAME ; File to create
866 0607 33 C9 XOR CX,CX ; Normal attribute
867 0609 CD 21 INT MS_DOS ; Create it
868 060B A3 09F1 R MOV WORD PTR [HANDLE],AX ; Save handle/error
869 060E 73 13 JNC CREOK
870 0610 BE 0C2B R MOV SI,OFFSET PRP4 ; Point to prompt
871 0613 E8 03D9 R CALL PROMPT
872 0616 BE 0CFA R MOV SI,OFFSET FNAME ; Point to filename
873 0619 E8 03D9 R CALL PROMPT ; Print to screen
874 061C BE 0C49 R MOV SI,OFFSET PRP6 ; End of the string
875 061F E8 03D9 R CALL PROMPT
876 0622 F9 STC ; Maintain error status
877 0623 C3 CREOK: RET
878 0624 OPEN_W ENDP
879 ;
880 0624 CLOSE PROC NEAR
881 0624 B8 3E00 MOV AX,3E00H ; Close file function
882 0627 8B 1E 09F1 R MOV BX,WORD PTR [HANDLE] ; Get file handle
883 062B CD 21 INT MS_DOS
884 062D C3 RET
885 062E CLOSE ENDP
886 ;
887 ; Read the file open for reading into the buffer.
888 ;
889 062E READ PROC NEAR
890 062E 80 3E 09ED R 0A CMP BYTE PTR [TRIES],MAX ; No retries?
891 0633 75 10 JNZ NOUP
892 0635 81 3E 09EB R 2000 CMP WORD PTR [BYTES],8192 ; Check upper limit
893 063B 73 16 JNC NODWN ; Don't add more
894 063D 81 06 09EB R 0200 ADD WORD PTR [BYTES],512 ; Send more bytes
895 0643 EB 0E JMP SHORT NODWN ; Continue
896 0645 81 3E 09EB R 0200 NOUP: CMP WORD PTR [BYTES],512 ; Already the lowest?
897 064B 74 06 JZ NODWN
898 064D 81 2E 09EB R 0200 SUB WORD PTR [BYTES],512 ; Get/send fewer bytes
899 ;
900 0653 8B 0E 09EB R NODWN: MOV CX,WORD PTR [BYTES] ; Get Bytes to read
901 0657 8B 1E 09F1 R MOV BX,WORD PTR [HANDLE] ; Get open file handle
902 065B B8 3F00 MOV AX,3F00H ; Read file/device
903 065E 1E PUSH DS ; Save segment
904 065F 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Pick up segment for output data
905 0663 BA 0004 MOV DX,IDATA ; Offset of the data
906 0666 CD 21 INT MS_DOS ; Read the data
907 0668 C6 06 0002 01 MOV BYTE PTR DS:[CTRL],NORMAL ; Assume normal read
908 066D 3B C1 CMP AX,CX ; Check for end of file
909 066F 74 0B JZ NORM ; Was not the end of file
910 0671 80 0E 0002 04 OR BYTE PTR DS:[CTRL],EOF ; Is the end of file
911 0676 26: C6 06 09E7 R 04 MOV BYTE PTR ES:[FEND],EOF ; Local info also
912 067C 8B C8 NORM: MOV CX,AX ; Save real byte count
913 067E 05 0006 ADD AX,6 ; Overhead
914 0681 A3 0000 MOV WORD PTR DS:[LEN],AX ; Bytes to transmit
915 ;
916 0684 06 PUSH ES ; Save segment
917 0685 1E PUSH DS
918 0686 07 POP ES ; ES=DS
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-18
919 0687 51 PUSH CX ; Save byte count for now
920 0688 8B C1 MOV AX,CX ; Count to encode
921 068A BE 0004 MOV SI,IDATA ; Where the data is
922 068D BF 4000 MOV DI,CODELOC ; Where to put coded data
923 0690 E8 072C R CALL ENCODE ; Encode the data
924 0693 59 POP CX ; Restore original byte count
925 0694 3B C1 CMP AX,CX ; Check to see if new is less
926 0696 73 1C JNC READ0 ; Not less
927 ;
928 0698 51 PUSH CX ; Save original byte count
929 0699 8B C8 MOV CX,AX ; New byte count
930 069B BE 4000 MOV SI,CODELOC ; When compressed data is
931 069E BF 0004 MOV DI,IDATA ; Where to put compressed data
932 06A1 F3/ A4 REP MOVSB ; Copy the data
933 06A3 05 0006 ADD AX,6 ; Add in overhead
934 06A6 A3 0000 MOV WORD PTR DS:[LEN],AX ; Bytes to actually transmit
935 06A9 80 26 0002 FE AND BYTE PTR DS:[CTRL],NONORM ; Reset, normal bit
936 06AE 80 0E 0002 02 OR BYTE PTR DS:[CTRL],COMP ; Show its encoded
937 06B3 59 POP CX ; Restore original byte count
938 ;
939 06B4 07 READ0: POP ES ; Restore segments
940 06B5 1F POP DS
941 06B6 01 0E 09E2 R ADD WORD PTR [CNT_LO],CX ; Add to the count
942 06BA 83 16 09E0 R 00 ADC WORD PTR [CNT_HI],0 ; Take care of overflow.
943 06BF FF 06 09E9 R INC WORD PTR [REC_NOL] ; Next record number
944 06C3 C3 RET
945 06C4 READ ENDP
946 ;
947 ; Write the buffer contents to the file
948 ;
949 06C4 WRITE PROC NEAR
950 06C4 1E PUSH DS
951 06C5 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Where the data is
952 06C9 BA 0004 MOV DX,IDATA ; Offset for data
953 06CC 8B 0E 0000 MOV CX,WORD PTR DS:[LEN] ; Get string length
954 06D0 83 E9 06 SUB CX,6 ; Remove overhead
955 06D3 F6 06 0002 02 TEST BYTE PTR DS:[CTRL],COMP ; Check for compressed data
956 06D8 74 13 JZ WRITE0 ; Its normal, not compressed
957 06DA 06 PUSH ES ; Save segment
958 06DB 1E PUSH DS
959 06DC 07 POP ES ; ES=DS
960 06DD 8B F2 MOV SI,DX ; Location of the string
961 06DF BF 4000 MOV DI,CODELOC ; Where to put the decoded data
962 06E2 8B C1 MOV AX,CX ; String length
963 06E4 E8 070F R CALL DECODE ; Decode the data
964 06E7 8B C8 MOV CX,AX ; New string length
965 06E9 BA 4000 MOV DX,CODELOC ; Where the data is
966 06EC 07 POP ES ; Restore segment
967 06ED 2E: 8B 1E 09F1 R WRITE0: MOV BX,WORD PTR CS:[HANDLE] ; Get the file access word
968 06F2 B8 4000 MOV AX,4000H ; Write to file/device
969 06F5 CD 21 INT MS_DOS
970 06F7 1F POP DS
971 06F8 9C PUSHF ; Save write status
972 06F9 89 0E 09EB R MOV WORD PTR [BYTES],CX ; For 'SHOW' routine
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-19
973 06FD 01 0E 09E2 R ADD WORD PTR [CNT_LO],CX ; Add to the count
974 0701 83 16 09E0 R 00 ADC WORD PTR [CNT_HI],0 ; Take care of overflow.
975 0706 FF 06 09E9 R INC WORD PTR [REC_NOL] ; Next record number
976 070A E8 07FC R CALL SHOW
977 070D 9D POPF ; Restore write status
978 070E C3 RET
979 070F WRITE ENDP
980 ;
981 ;
982 ; Decode compressed string in DS:SI and transfer to ES:DI
983 ; Input string length is in AX, output string length in AX
984 ;
985 070F DECODE PROC NEAR
986 070F 57 PUSH DI ; SAVE START ADDRESS
987 0710 8B DE MOV BX,SI ; GET STARTING OFFSET
988 0712 03 D8 ADD BX,AX ; CALC END OF STRING OFFSET
989 0714 AC DECD0: LODSB ; GET BYTE
990 0715 3C BB CMP AL,0BBH ; SENTINEL ?
991 0717 75 08 JNZ DECD1 ; NO
992 0719 AD LODSW ; PICK UP LENGTH
993 071A 8B C8 MOV CX,AX ; UPDATE BYTE COUNT
994 071C AC LODSB ; GET REPEAT CHARACTER
995 071D F3/ AA REP STOSB ; FILL IN CHARACTER
996 071F EB 01 JMP SHORT DECD2 ; AND CONTINUE
997 0721 AA DECD1: STOSB ; TRANSFER BYTE
998 0722 3B F3 DECD2: CMP SI,BX ; END OF STRING?
999 0724 72 EE JC DECD0 ; NOT YET
1000 0726 8B C7 MOV AX,DI ; GET ENDING STRING OFFSET
1001 0728 5F POP DI ; RESTORE START ADDRESS
1002 0729 2B C7 SUB AX,DI ; SUBTRACT START
1003 072B C3 RET ; AX = BYTE COUNT
1004 072C DECODE ENDP
1005 ;
1006 ; Encode string in DS:SI. Output string in ES:DI. Upon input
1007 ; AX = Byte count. Upon output AX = new string length
1008 ;
1009 072C ENCODE PROC NEAR
1010 072C 52 PUSH DX
1011 072D 57 PUSH DI ; SAVE OUTPUT STRING LOC
1012 072E 03 C6 ADD AX,SI ; CALC LAST ADDRESS
1013 0730 8B D0 MOV DX,AX ; SAVE LAST ADDESSS
1014 0732 AC ENCD0: LODSB ; GET BYTE
1015 0733 56 PUSH SI ; SAVE SOURCE INDEX
1016 0734 57 PUSH DI ; SAVE DEST INDEX
1017 0735 8B CA MOV CX,DX ; GET LAST POSSIBLE ADDRESS
1018 0737 2B CE SUB CX,SI ; SUBTRACT PRESENT ADDRESS
1019 0739 41 INC CX ; ADD ONE
1020 ;
1021 073A 8B FE MOV DI,SI ; FOR SEARCH DI=POINTER
1022 073C F3/ AE REPZ SCASB ; SEE HOW MANY THERE ARE
1023 073E 8B DF MOV BX,DI ; GET LAST ADDRESS
1024 ;
1025 0740 5F POP DI ; RESTORE REGISTERS
1026 0741 5E POP SI
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-20
1027 0742 2B DE SUB BX,SI ; BX = BYTE COUNT
1028 0744 3C BB CMP AL,0BBH ; WAS IT THE SENTINEL?
1029 0746 74 05 JZ ENCD1 ; YES, REQUIRES ENCODING
1030 0748 83 FB 04 CMP BX,4 ; ENOUGH TO COMPACT?
1031 074B 72 0B JC NOENC ; NO, DON'T ENCODE
1032 074D 50 ENCD1: PUSH AX ; SAVE BYTE
1033 074E B0 BB MOV AL,0BBH ; SENTINEL
1034 0750 AA STOSB ; PUT IN OUTPUT BUFFER
1035 0751 8B C3 MOV AX,BX ; BYTE COUNT
1036 0753 AB STOSW ; INTO BUFFER
1037 0754 58 POP AX ; RESTORE SAVED BYTE
1038 0755 4B DEC BX ; LODSB INCREMENTED IT ONCE
1039 0756 03 F3 ADD SI,BX ; UPDATE SOURCE
1040 0758 AA NOENC: STOSB ; SAVE BYTE
1041 0759 3B F2 ENCD2: CMP SI,DX ; CHECK LIMITS
1042 075B 72 D5 JC ENCD0 ; CONTINUE
1043 075D 8B C7 ENCD3: MOV AX,DI ; GET LAST ADDRESS
1044 075F 5F POP DI ; RESTORE START ADDRESS
1045 0760 2B C7 SUB AX,DI ; CALC BYTE COUNT
1046 0762 5A POP DX
1047 0763 C3 RET
1048 0764 ENCODE ENDP
1049 ;
1050 ; Parse the command line to extract filename and function.
1051 ;
1052 0764 PARSE PROC NEAR
1053 0764 BE 0E90 R MOV SI,OFFSET COMINIT ; Assume COM1
1054 0767 BF 0A10 R MOV DI,OFFSET PORT ; Where to put the data
1055 076A B9 0004 90 MOV CX,CLEN ; Length of string to move
1056 076E F3/ A4 REP MOVSB ; Fill the table
1057 0770 BE 0080 MOV SI,80H
1058 0773 AC LODSB ; Get bytes typed
1059 0774 3C 03 CMP AL,3 ; Nothing?
1060 0776 72 22 JC PARSEX ; Yes, nothing typed
1061 0778 98 CBW
1062 0779 8B C8 MOV CX,AX ; Use as a count
1063 077B E8 07DE R CALL MAP ; Map to upper case
1064 077E 49 DEC CX
1065 077F 49 DEC CX
1066 0780 AC PARSE0: LODSB ; Get byte
1067 0781 3C 20 CMP AL,' ' ; Is it a space (or less)
1068 0783 76 04 JBE PARSE1 ; Space found
1069 0785 E2 F9 LOOP PARSE0 ; None, continue
1070 0787 EB 11 JMP SHORT PARSEX ; Not found, exit with error
1071 ;
1072 0789 80 3C 20 PARSE1: CMP BYTE PTR [SI],' ' ; Check next byte
1073 078C 76 F2 JBE PARSE0 ; Yes
1074 078E AC LODSB ; Get the byte
1075 078F 49 DEC CX ; Byte count
1076 0790 E3 08 JCXZ PARSEX ; Ran out of characters
1077 0792 3C 52 CMP AL,'R' ; Was it a [R]eceive?
1078 0794 74 06 JZ YES ; Yes
1079 0796 3C 53 CMP AL,'S' ; Was it a [S]end?
1080 0798 74 02 JZ YES ; Yes
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-21
1081 079A F9 PARSEX: STC ; Show error and exit
1082 079B C3 RET
1083 ;
1084 079C A2 09EE R YES: MOV BYTE PTR [RXTX],AL ; Save flag
1085 079F 80 3C 20 CMP BYTE PTR [SI],' ' ; More spaces?
1086 07A2 76 26 JBE PARSE2 ; Filter them all
1087 07A4 AC LODSB ; Get port
1088 07A5 49 DEC CX ; Bump byte count
1089 07A6 E3 F2 JCXZ PARSEX ; Ran out of bytes
1090 07A8 2C 30 SUB AL,'0' ; Remove ASCII bias
1091 07AA 76 1E JBE PARSE2 ; Lower limit
1092 07AC 3C 04 CMP AL,4 ; Check upper limit
1093 07AE 7F 1A JG PARSE2 ; Out of limits
1094 07B0 FE C8 DEC AL ; COM one = offset zero
1095 07B2 32 E4 XOR AH,AH ; Zero high byte
1096 07B4 D1 E0 SHL AX,1 ; Times two
1097 07B6 D1 E0 SHL AX,1 ; Times four
1098 07B8 56 PUSH SI ; Save command line location
1099 07B9 BE 0E90 R MOV SI,OFFSET COMINIT ; Where the table
1100 07BC 03 F0 ADD SI,AX ; Offset for COM1,,,4
1101 07BE BF 0A10 R MOV DI,OFFSET PORT ; Runtime parameters
1102 07C1 51 PUSH CX ; Save count
1103 07C2 B9 0004 90 MOV CX,CLEN ; Four bytes
1104 07C6 F3/ A4 REP MOVSB ; Insert new parameters
1105 07C8 59 POP CX ; Restore count
1106 07C9 5E POP SI ; Restore command line location
1107 07CA AC PARSE2: LODSB
1108 07CB 3C 20 CMP AL,' ' ; Look for another space
1109 07CD 76 04 JBE PARSE3
1110 07CF E2 F9 LOOP PARSE2
1111 07D1 EB C7 JMP SHORT PARSEX ; No more spaces
1112 ;
1113 07D3 80 3C 20 PARSE3: CMP BYTE PTR [SI],' ' ; More spaces?
1114 07D6 76 F2 JBE PARSE2 ; Filter them all
1115 07D8 BF 0CFA R MOV DI,OFFSET FNAME ; We got to the filename
1116 07DB F3/ A4 REP MOVSB ; Copy it
1117 07DD C3 RET
1118 07DE PARSE ENDP
1119 ;
1120 ; Map string addressed by SI to upper case. CX = byte count.
1121 ;
1122 07DE MAP PROC NEAR
1123 07DE 51 PUSH CX
1124 07DF 56 PUSH SI
1125 07E0 57 PUSH DI
1126 07E1 8B FE MOV DI,SI ; Copy for same offset
1127 07E3 AC MAP0: LODSB ; Get byte
1128 07E4 3C 7A CMP AL,'z' ; Check upper limit
1129 07E6 77 06 JA MAP1 ; Not a lower case character
1130 07E8 3C 61 CMP AL,'a' ; Check lower limit
1131 07EA 72 02 JB MAP1 ; Not a lower case character
1132 07EC 24 5F AND AL,95 ; Reset lower case bits
1133 07EE AA MAP1: STOSB ; Replace in the string
1134 07EF E2 F2 LOOP MAP0
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-22
1135 07F1 5F POP DI
1136 07F2 5E POP SI
1137 07F3 59 POP CX
1138 07F4 C3 RET
1139 07F5 MAP ENDP
1140 ;
1141 ; Control Break not allowed.
1142 ;
1143 07F5 BRK PROC FAR
1144 07F5 2E: C6 06 09DD R FF MOV BYTE PTR CS:[KILL],0FFH ; Set the flag.
1145 07FB CF IRET
1146 07FC BRK ENDP
1147 ;
1148 07FC SHOW PROC NEAR
1149 07FC 33 C0 XOR AX,AX ; Get current time
1150 07FE CD 1A INT 1AH ; Get the time
1151 0800 A1 09DB R MOV AX,WORD PTR [TIM_L] ; Get Last time
1152 0803 89 16 09DB R MOV WORD PTR [TIM_L],DX ; Save new LOW count
1153 0807 2B D0 SUB DX,AX ; Sub new LOW from old
1154 0809 72 03 JC NOCY
1155 080B 83 C2 FF ADD DX,0FFFFH ; Must have gone past the hour
1156 080E 8B CA NOCY: MOV CX,DX ; Save low count
1157 0810 75 03 JNZ NOZER ; Not a zero
1158 0812 B9 0001 MOV CX,1 ; Make zero one
1159 0815 A1 09EB R NOZER: MOV AX,WORD PTR [BYTES] ; Get bytes TX/RX this time
1160 0818 33 D2 XOR DX,DX ; Ready for DIV
1161 081A F7 F1 DIV CX ; AX = bytes / tick
1162 081C B9 0013 MOV CX,19
1163 081F F7 E1 MUL CX
1164 ;
1165 0821 06 PUSH ES
1166 0822 8E 06 0A0E R MOV ES,WORD PTR [SCR_SEG] ; Pick up screen segment
1167 ;
1168 0826 BF 072C MOV DI,SCR_CPS
1169 0829 33 D2 XOR DX,DX ; Zero high word
1170 082B E8 0862 R CALL ASCII
1171 082E B8 7020 MOV AX,(SCRATTR SHL 8) OR 20H ; Normal attribute and a space
1172 0831 AB STOSW
1173 ;
1174 0832 A1 09E9 R MOV AX,WORD PTR [REC_NOL] ; Get record number
1175 0835 33 D2 XOR DX,DX ; Set high word
1176 0837 BF 054C MOV DI,SCR_BLK ; Where to put the data
1177 083A E8 0862 R CALL ASCII ; Convert
1178 ;
1179 083D 1E PUSH DS ; Save segment
1180 083E 8E 1E 09F3 R MOV DS,WORD PTR [BUF_SEG] ; Get buffer segment
1181 0842 A1 0000 MOV AX,WORD PTR DS:[LEN] ; Get bytes
1182 0845 1F POP DS ; Restore segment
1183 0846 33 D2 XOR DX,DX ; Zero high word
1184 0848 BF 05EC MOV DI,SCR_LEN ; Where to put the ASCII
1185 084B E8 0862 R CALL ASCII ; Convert to ascii
1186 084E B8 7020 MOV AX,(SCRATTR SHL 8) OR 20H ; Normal attribute and a space
1187 0851 AB STOSW
1188 0852 AB STOSW
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-23
1189 ;
1190 0853 8B 16 09E0 R MOV DX,WORD PTR [CNT_HI] ; Pick up byte count
1191 0857 A1 09E2 R MOV AX,WORD PTR [CNT_LO]
1192 085A BF 068C MOV DI,SCR_BYT ; Where to put the data
1193 085D E8 0862 R CALL ASCII ; Convert to ASCII decimal
1194 ;
1195 0860 07 POP ES
1196 0861 C3 RET
1197 0862 SHOW ENDP
1198 ;
1199 ; Print double precision number in DX:AX. The string is addressed by DI
1200 ; All registers except BP are destroyed by this call.
1201 ;
1202 0862 ASCII PROC NEAR
1203 0862 BD 0000 MOV BP,0000 ; Leading zero flag
1204 0865 B9 3B9A MOV CX,3B9AH ; Get billions
1205 0868 BB CA00 MOV BX,0CA00H
1206 086B E8 08C5 R CALL SUBTR ; Subtract them out
1207 086E E8 08E6 R CALL COMMA ; Put in a comma
1208 0871 B9 05F5 MOV CX,05F5H ; Get hundred-millions
1209 0874 BB E100 MOV BX,0E100H
1210 0877 E8 08C5 R CALL SUBTR ; Subtract them out
1211 087A B9 0098 MOV CX,0098H ; Get ten-millions
1212 087D BB 9680 MOV BX,9680H
1213 0880 E8 08C5 R CALL SUBTR ; Subtract them out
1214 0883 B9 000F MOV CX,000FH ; Get millions
1215 0886 BB 4240 MOV BX,4240H
1216 0889 E8 08C5 R CALL SUBTR ; Subtract them out
1217 088C E8 08E6 R CALL COMMA ; Put in a comma
1218 088F B9 0001 MOV CX,0001H ; Get hundred-thousands
1219 0892 BB 86A0 MOV BX,86A0H
1220 0895 E8 08C5 R CALL SUBTR ; Subtract them out
1221 0898 B9 0000 MOV CX,0000H ; Get ten-thousands
1222 089B BB 2710 MOV BX,2710H
1223 089E E8 08C5 R CALL SUBTR ; Subtract them out
1224 08A1 B9 0000 MOV CX,0000H ; Get thousands
1225 08A4 BB 03E8 MOV BX,03E8H
1226 08A7 E8 08C5 R CALL SUBTR ; Subtract them out
1227 08AA E8 08E6 R CALL COMMA ; Put in a comma
1228 08AD B9 0000 MOV CX,0000H ; Get hundreds
1229 08B0 BB 0064 MOV BX,0064H
1230 08B3 E8 08C5 R CALL SUBTR ; Subtract them out
1231 08B6 B9 0000 MOV CX,0000H ; Get tens
1232 08B9 BB 000A MOV BX,000AH
1233 08BC E8 08C5 R CALL SUBTR ; Subtract them out
1234 08BF 04 30 ADD AL,'0' ; Add bias to residual
1235 08C1 B4 70 MOV AH,SCRATTR ; Normal attribute
1236 08C3 AB STOSW ; Put in the string
1237 08C4 C3 RET
1238 ;
1239 08C5 BE 002F SUBTR: MOV SI,'0'-1 ; We are out of registers!
1240 08C8 46 SUBTR1: INC SI ; Counter
1241 08C9 2B C3 SUB AX,BX ; Dword subtraction
1242 08CB 1B D1 SBB DX,CX
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-24
1243 08CD 73 F9 JNB SUBTR1 ; Continue until a carry
1244 08CF 03 C3 ADD AX,BX ; One too many, add back
1245 08D1 13 D1 ADC DX,CX ; and the remainder
1246 08D3 83 FD 00 CMP BP,0 ; See if we printed anything yet
1247 08D6 75 05 JNZ SUBTR2 ; No, can't be a leading zero
1248 08D8 83 FE 30 CMP SI,'0' ; See if its a zero
1249 08DB 74 08 JZ SUBTR3 ; Yes, don't print them
1250 ;
1251 08DD 45 SUBTR2: INC BP ; We are now 'printing' a character
1252 08DE 50 PUSH AX ; Save accumulator
1253 08DF 8B C6 MOV AX,SI ; Get index
1254 08E1 B4 70 MOV AH,SCRATTR ; Attribute byte
1255 08E3 AB STOSW ; Put in screen memory
1256 08E4 58 POP AX ; Restore accumulator
1257 08E5 C3 SUBTR3: RET
1258 ;
1259 08E6 83 FD 00 COMMA: CMP BP,0 ; Any bytes printed?
1260 08E9 74 07 JZ PASS ; No, then no commas
1261 08EB 50 PUSH AX ; Yes, save
1262 08EC B0 2C MOV AL,',' ; Get a comma
1263 08EE B4 70 MOV AH,SCRATTR ; Attribute
1264 08F0 AB STOSW ; Into string
1265 08F1 58 POP AX ; Restore
1266 08F2 C3 PASS: RET
1267 08F3 ASCII ENDP
1268 ;
1269 ; Send 10 control-Xes to remote to cause an abort.
1270 ;
1271 08F3 SENDX PROC NEAR
1272 08F3 B9 000A MOV CX,10 ; Bytes to send
1273 08F6 B0 18 SENDX0: MOV AL,CAN ; Control-x
1274 08F8 E8 02A6 R CALL FORCE ; Send (no flow control)the byte
1275 08FB E2 F9 LOOP SENDX0 ; Continue for all bytes
1276 08FD C3 RET
1277 08FE SENDX ENDP
1278 ;
1279 ; Save any information in the screen regen buffer.
1280 ;
1281 08FE SAV_SCR PROC NEAR
1282 08FE C6 06 09DE R FF MOV BYTE PTR [SCR_SAV],0FFH ; Set entry flag
1283 0903 B8 0500 MOV AX,0500H ; Select page zero
1284 0906 CD 10 INT VIDEO ; Do it
1285 ;
1286 0908 B8 0300 MOV AX,0300H ; Get cursor position
1287 090B BB 0000 MOV BX,0 ; Page zero
1288 090E CD 10 INT VIDEO ; Get the cursor position
1289 0910 89 16 0A0C R MOV WORD PTR [CUR_POS],DX ; Save the position
1290 ;
1291 0914 B8 0200 MOV AX,0200H ; Set cursor position
1292 0917 BB 0000 MOV BX,0 ; Page zero
1293 091A BA 1A00 MOV DX,1A00H ; Hide off screen
1294 091D CD 10 INT VIDEO ; Set the position
1295 ;
1296 091F 1E PUSH DS ; Save data segment
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-25
1297 0920 8E 1E 0A0E R MOV DS,WORD PTR [SCR_SEG] ; Pick up screen segment
1298 0924 BE 03F6 MOV SI,ORIGIN ; Where we will put logo
1299 0927 BF 0AB5 R MOV DI,OFFSET SCR_BUF ; Where to save the data
1300 092A B9 0007 MOV CX,7 ; Lines to save
1301 092D 51 SAV0: PUSH CX ; Save count
1302 092E B9 0017 MOV CX,LINLEN ; Length of line
1303 0931 F3/ A5 REP MOVSW ; Copy to buffer
1304 0933 83 C6 72 ADD SI,160 - (LINLEN *2) ; Next line
1305 0936 59 POP CX ; Restore count
1306 0937 E2 F4 LOOP SAV0 ; Continue for all lines
1307 0939 1F POP DS ; Restore segment
1308 093A C3 RET
1309 093B SAV_SCR ENDP
1310 ;
1311 ; Restore saved bytes/attributes to the screen regen buffer
1312 ;
1313 093B RES_SCR PROC NEAR
1314 093B 80 3E 09DE R 00 CMP BYTE PTR [SCR_SAV],0 ; Did we save the screen?
1315 0940 75 01 JNZ RESIT ; Yes
1316 0942 C3 RET ; No, don't restore
1317 0943 C6 06 09DE R 00 RESIT: MOV BYTE PTR [SCR_SAV],0 ; Show its already been restored.
1318 0948 06 PUSH ES ; Save segment
1319 0949 8E 06 0A0E R MOV ES,WORD PTR [SCR_SEG] ; Pick up screen segment
1320 094D BF 03F6 MOV DI,ORIGIN ; Where to start
1321 0950 BE 0AB5 R MOV SI,OFFSET SCR_BUF ; Where the saved data are
1322 0953 B9 0007 MOV CX,7 ; Lines to restore
1323 0956 51 RES0: PUSH CX ; Save count
1324 0957 B9 0017 MOV CX,LINLEN ; Line length
1325 095A F3/ A5 REP MOVSW ; Move to screen buffer
1326 095C 83 C7 72 ADD DI,160 - ( LINLEN * 2 ) ; Ready next line
1327 095F 59 POP CX ; Restore line count
1328 0960 E2 F4 LOOP RES0 ; Continue for all lines
1329 0962 07 POP ES ; Restore segment
1330 ;
1331 0963 B8 0200 MOV AX,0200H ; Set cursor position
1332 0966 BB 0000 MOV BX,0 ; Page zero
1333 0969 8B 16 0A0C R MOV DX,WORD PTR [CUR_POS] ; Get old position
1334 096D CD 10 INT VIDEO ; Set the position
1335 096F C3 RET
1336 0970 RES_SCR ENDP
1337 ;
1338 ; Write status block to the screen.
1339 ;
1340 0970 WRT_SCR PROC NEAR
1341 0970 06 PUSH ES ; Save segment
1342 0971 8E 06 0A0E R MOV ES,WORD PTR [SCR_SEG] ; Pick up screen segment
1343 0975 BE 0A14 R MOV SI,OFFSET LIN1 ; Data for line
1344 0978 BF 03F6 MOV DI,ORIGIN ; Screen regen buffer
1345 097B B9 0007 MOV CX,7 ; Number of lines
1346 097E B4 70 MOV AH,SCRATTR ; Attribute
1347 0980 51 WRT0: PUSH CX ; Save line count
1348 0981 B9 0017 MOV CX,LINLEN ; Get length of the line
1349 0984 AC WRT1: LODSB ; Get byte from logo
1350 0985 AB STOSW ; Save a word in screen memory
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-26
1351 0986 E2 FC LOOP WRT1 ; Continue for the line
1352 0988 83 C7 72 ADD DI,160 - (LINLEN * 2) ; Offset to next line
1353 098B 59 POP CX ; Restore line count
1354 098C E2 F2 LOOP WRT0 ; Continue for all lines
1355 098E 07 POP ES ; Restore segment
1356 098F C3 RET
1357 0990 WRT_SCR ENDP
1358 ;
1359 ; Get segment address for screen regen buffer and base/status port for
1360 ; the video controller. Save addresses in code segment.
1361 ;
1362 0990 FIND_VIDEO PROC NEAR
1363 0990 1E PUSH DS ; Save present
1364 0991 B8 ---- R MOV AX,BSEG ; Get BIOS segment
1365 0994 8E D8 MOV DS,AX ; Into ours
1366 0996 81 3E 0063 R 03D0 CMP WORD PTR DS:[ADDR_6845],3D0H
1367 099C 1F POP DS ; Restore the data segment
1368 099D B8 B800 MOV AX,0B800H ; Segment for color
1369 09A0 73 03 JAE COLOR ; Yes, its correct
1370 09A2 B8 B000 MOV AX,0B000H ; Must be B&W
1371 09A5 A3 0A0E R COLOR: MOV WORD PTR [SCR_SEG],AX ; Save for later
1372 ;
1373 09A8 1E PUSH DS
1374 09A9 8E 1E 0A0E R MOV DS,WORD PTR [SCR_SEG] ; Pick up screen segment
1375 09AD A1 0000 MOV AX,WORD PTR DS:[0] ; Get first word
1376 09B0 F7 D0 NOT AX ; Invert it
1377 09B2 A3 0000 MOV WORD PTR DS:[0],AX ; Put back in screen memory
1378 09B5 50 PUSH AX ; Exercise bus
1379 09B6 58 POP AX
1380 09B7 39 06 0000 CMP WORD PTR DS:[0],AX ; See if it went
1381 09BB 9C PUSHF ; Save result
1382 09BC F7 16 0000 NOT WORD PTR DS:[0] ; Change back to normal
1383 09C0 9D POPF
1384 09C1 1F POP DS ; Restore segment
1385 09C2 75 01 JNZ CHKMEM ; Memory was not writable
1386 09C4 C3 RET
1387 ;
1388 09C5 81 3E 0A0E R B000 CHKMEM: CMP WORD PTR [SCR_SEG],0B000H ; See if mono
1389 09CB 74 07 JZ MONO
1390 ;
1391 ; Color didn't work, change to Mono
1392 ;
1393 09CD C7 06 0A0E R B000 MOV WORD PTR [SCR_SEG],0B000H
1394 09D3 C3 RET
1395 ;
1396 ; Mono didn't work, change to color
1397 ;
1398 09D4 C7 06 0A0E R B800 MONO: MOV WORD PTR [SCR_SEG],0B800H
1399 09DA C3 RET
1400 09DB FIND_VIDEO ENDP
1401 ;
1402 09DB ???? TIM_L DW ? ; Transfer time Low word
1403 ;
1404 09DD 00 KILL DB 0 ; Abort program.
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-27
1405 09DE 00 SCR_SAV DB 0 ; Flag to show we saved the screen.
1406 09DF 00 INT_FLG DB 0 ; Flag to show hot interrupts
1407 09E0 0000 CNT_HI DW 0 ; Transfer byte count
1408 09E2 0000 CNT_LO DW 0 ; Low word of above.
1409 09E4 00 ENABLE DB 0 ; TX enable bytes
1410 09E5 00 WASC DB 0 ; Flag for carrier
1411 09E6 00 STATUS DB 0 ; Port status
1412 09E7 00 FEND DB 0 ; End of file?
1413 09E8 00 MOD_STA DB 0 ; Modem status at interrupt time
1414 09E9 0000 REC_NOL DW 0 ; Record number of file to send/rec
1415 = 000E KLEN EQU $ - KILL ; Length to zero out
1416 09EB 0400 BYTES DW 1024 ; Bytes to read/send
1417 09ED ?? TRIES DB ? ; Attempts to send a block
1418 09EE ?? RXTX DB ? ; Receive/transm flag
1419 09EF ???? CLOCK DW ? ; Local timer
1420 09F1 ???? HANDLE DW ? ; File handle
1421 09F3 ???? BUF_SEG DW ? ; Segment of buffer
1422 09F5 ???? DAT_SEG DW ? ; Next 64k segment
1423 09F7 OLD_CLK LABEL DWORD ; Old clock vector
1424 09F7 ???? CLK_OFF DW ? ; Clock offset
1425 09F9 ???? CLK_SEG DW ? ; Clock segment
1426 09FB OLD_BRK LABEL DWORD ; Old break key vector
1427 09FB ???? BRK_OFF DW ?
1428 09FD ???? BRK_SEG DW ?
1429 09FF OLD_CTC LABEL DWORD ; Old ^C vector
1430 09FF ???? CTC_OFF DW ?
1431 0A01 ???? CTC_SEG DW ?
1432 0A03 OLD_UART LABEL DWORD ; Old UART interrupt address
1433 0A03 ???? UAR_OFF DW ? ; Its offset
1434 0A05 ???? UAR_SEG DW ? ; and segment
1435 0A07 ?? OLD_MASK DB ? ; Old interrupt masm
1436 0A08 ???? BYTE_CNT DW ? ; Interrupt byte count
1437 0A0A ???? WPOINT DW ? ; Write pointer for interrupt
1438 0A0C ???? CUR_POS DW ? ; Saved cursor position
1439 0A0E ???? SCR_SEG DW ? ; Screen segment
1440 ;
1441 0A10 ???? PORT DW ? ; Communications adapter port
1442 0A12 ?? COM_INT DB ? ; Communications adapter interrupt
1443 0A13 ?? COM_MSK DB ? ; Communications adapter contr mask
1444 ;
1445 0A14 C9 LIN1 DB 201
1446 0A15 0015[ DB 21 DUP (205)
1447 CD
1448 ]
1449
1450 0A2A BB DB 187
1451 0A2B BA 20 4A 20 4D 20 4F DB 186,' J M O D E M Status ',186
1452 20 44 20 45 20 4D 20
1453 20 53 74 61 74 75 73
1454 20 BA
1455 0A42 BA 20 20 42 6C 6F 63 DB 186,' Block : ',186
1456 6B 20 3A 20 20 20 20
1457 20 20 20 20 20 20 20
1458 20 BA
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-28
1459 0A59 BA 20 4C 65 6E 67 74 DB 186,' Length : ',186
1460 68 20 3A 20 20 20 20
1461 20 20 20 20 20 20 20
1462 20 BA
1463 0A70 BA 20 20 42 79 74 65 DB 186,' Bytes : ',186
1464 73 20 3A 20 20 20 20
1465 20 20 20 20 20 20 20
1466 20 BA
1467 0A87 BA 20 20 20 52 61 74 DB 186,' Rate : cps ',186
1468 65 20 3A 20 20 20 20
1469 20 20 20 20 63 70 73
1470 20 BA
1471 0A9E C8 DB 200
1472 0A9F 0015[ DB 21 DUP (205)
1473 CD
1474 ]
1475
1476 0AB4 BC DB 188
1477 ;
1478 ; Screen "window" contents will be saved here.
1479 ;
1480 0AB5 SCR_BUF LABEL BYTE
1481 0AB5 0D 0A 20 20 20 20 20 PRP3 DB CR,LF,' J M O D E M File transfer system '
1482 20 20 20 20 20 4A 20
1483 4D 20 4F 20 44 20 45
1484 20 4D 20 20 46 69 6C
1485 65 20 74 72 61 6E 73
1486 66 65 72 20 73 79 73
1487 74 65 6D 20
1488 0AE3 56312E3035 VERS <>
1489
1490 0AE8 0D 0A 20 20 20 20 20 DB CR,LF,' Created by Richard B. Johnson'
1491 20 20 20 20 20 20 20
1492 20 43 72 65 61 74 65
1493 64 20 62 79 20 20 20
1494 20 52 69 63 68 61 72
1495 64 20 42 2E 20 4A 6F
1496 68 6E 73 6F 6E
1497 0B17 0D 0A 20 20 20 20 20 DB CR,LF,' PROGRAM EXCHANGE (719) 548-0208'
1498 20 20 20 20 20 20 20
1499 20 50 52 4F 47 52 41
1500 4D 20 45 58 43 48 41
1501 4E 47 45 20 20 28 37
1502 31 39 29 20 35 34 38
1503 2D 30 32 30 38
1504 0B46 0D 0A 55 73 61 67 65 DB CR,LF,'Usage:'
1505 3A
1506 0B4E 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM S1 <filename.typ> (to send a file via COM1)'
1507 4D 20 53 31 20 3C 66
1508 69 6C 65 6E 61 6D 65
1509 2E 74 79 70 3E 20 20
1510 28 74 6F 20 73 65 6E
1511 64 20 61 20 66 69 6C
1512 65 20 76 69 61 20 43
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-29
1513 4F 4D 31 29
1514 0B83 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM R1 <filename.typ> (to receive a file via COM1)'
1515 4D 20 52 31 20 3C 66
1516 69 6C 65 6E 61 6D 65
1517 2E 74 79 70 3E 20 20
1518 28 74 6F 20 72 65 63
1519 65 69 76 65 20 61 20
1520 66 69 6C 65 20 76 69
1521 61 20 43 4F 4D 31 29
1522 0BBB 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM S2 <filename.typ> (to send a file via COM2)'
1523 4D 20 53 32 20 3C 66
1524 69 6C 65 6E 61 6D 65
1525 2E 74 79 70 3E 20 20
1526 28 74 6F 20 73 65 6E
1527 64 20 61 20 66 69 6C
1528 65 20 76 69 61 20 43
1529 4F 4D 32 29
1530 0BF0 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM R2 <filename.typ> (to receive a file via COM2)'
1531 4D 20 52 32 20 3C 66
1532 69 6C 65 6E 61 6D 65
1533 2E 74 79 70 3E 20 20
1534 28 74 6F 20 72 65 63
1535 65 69 76 65 20 61 20
1536 66 69 6C 65 20 76 69
1537 61 20 43 4F 4D 32 29
1538 0C28 0D 0A 00 CRLF DB CR,LF,0
1539 0C2B 0D 0A 53 70 65 63 69 PRP4 DB CR,LF,'Specified file ',0
1540 66 69 65 64 20 66 69
1541 6C 65 20 00
1542 0C3D 20 6E 6F 74 20 66 6F PRP5 DB ' not found.',0
1543 75 6E 64 2E 00
1544 0C49 20 43 61 6E 27 74 20 PRP6 DB ' Can''t be created.',0
1545 62 65 20 63 72 65 61
1546 74 65 64 2E 00
1547 0C5C 0D 0A 53 65 6E 64 69 PRP7 DB CR,LF,'Sending file ',0
1548 6E 67 20 66 69 6C 65
1549 20 00
1550 0C6C 0D 0A 52 65 63 65 69 PRP8 DB CR,LF,'Receiving file ',0
1551 76 69 6E 67 20 66 69
1552 6C 65 20 00
1553 0C7E 0D 0A 46 69 6C 65 20 PRP9 DB CR,LF,'File transfer aborted!',0
1554 74 72 61 6E 73 66 65
1555 72 20 61 62 6F 72 74
1556 65 64 21 00
1557 0C97 0D 0A 46 69 6C 65 20 PRP10 DB CR,LF,'File transfer complete.',0
1558 74 72 61 6E 73 66 65
1559 72 20 63 6F 6D 70 6C
1560 65 74 65 2E 00
1561 0CB1 0D 0A 4D 6F 64 65 6D PRP11 DB CR,LF,'Modem carrier failed.',0
1562 20 63 61 72 72 69 65
1563 72 20 66 61 69 6C 65
1564 64 2E 00
1565 0CC9 20 20 5B 20 53 79 6E PRP12 DB ' [ Synchronized ] ',CR,LF,0
1566 63 68 72 6F 6E 69 7A
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Page 1-30
1567 65 64 20 5D 20 0D 0A
1568 00
1569 0CDF 20 20 5B 20 53 79 6E PRP13 DB ' [ Synchronizing ] '
1570 63 68 72 6F 6E 69 7A
1571 69 6E 67 20 5D 20
1572 0CF3 56312E3035 VERS <>
1573
1574 0CF8 0D 00 DB CR,0
1575 0CFA 0040[ FNAME DB 64 DUP (0)
1576 00
1577 ]
1578
1579 0D3A 0040[ ONAME DB 64 DUP (0)
1580 00
1581 ]
1582
1583 ;
1584 0D80 ORG ((($ - START) + 16) AND 0FFF0H)
1585 0D80 0020[ DB 32 DUP ('STACK ')
1586 53 54 41 43 4B
1587 20 20 20
1588 ]
1589
1590 0E80 STACKP LABEL WORD
1591 ;
1592 0E90 ORG ((($ - START) + 16) AND 0FFF0H)
1593 ;
1594 ; The following is used only once during initialization and will be
1595 ; overwritten with data once file transfer starts
1596 ;
1597 0E90 BUFFER LABEL BYTE
1598 0E90 03F8 COMINIT COM1<> ; COM1 parameters
1599 0E92 0C
1600 0E93 EF
1601
1602 = 0004 CLEN EQU $ - COMINIT ; Length of data to move
1603 0E94 02F8 COM2<> ; COM2 parameters
1604 0E96 0B
1605 0E97 F7
1606
1607 0E98 03E8 COM3<> ; COM3 parameters
1608 0E9A 0C
1609 0E9B EF
1610
1611 0E9C 02E8 COM4<> ; COM4 parameters
1612 0E9E 0B
1613 0E9F F7
1614
1615 0EA0 PSEG ENDS
1616 END MAIN
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Symbols-1
Structures and Records:
N a m e Width # fields
Shift Width Mask Initial
COM1 . . . . . . . . . . . . . . 0004 0003
COM1PRT . . . . . . . . . . . 0000
COM1INT . . . . . . . . . . . 0002
COM1MSK . . . . . . . . . . . 0003
COM2 . . . . . . . . . . . . . . 0004 0003
COM2PRT . . . . . . . . . . . 0000
COM2INT . . . . . . . . . . . 0002
COM2MSK . . . . . . . . . . . 0003
COM3 . . . . . . . . . . . . . . 0004 0003
COM3PRT . . . . . . . . . . . 0000
COM3INT . . . . . . . . . . . 0002
COM3MSK . . . . . . . . . . . 0003
COM4 . . . . . . . . . . . . . . 0004 0003
COM4PRT . . . . . . . . . . . 0000
COM4INT . . . . . . . . . . . 0002
COM4MSK . . . . . . . . . . . 0003
IBUFFER . . . . . . . . . . . . 0005 0004
LEN . . . . . . . . . . . . . 0000
CTRL . . . . . . . . . . . . . 0002
RECN . . . . . . . . . . . . . 0003
IDATA . . . . . . . . . . . . 0004
VERS . . . . . . . . . . . . . . 0005 0001
Segments and Groups:
N a m e Length Align Combine Class
BSEG . . . . . . . . . . . . . . 0065 AT 0040
PSEG . . . . . . . . . . . . . . 0EA0 PARA PUBLIC 'CODE'
Symbols:
N a m e Type Value Attr
ABORT . . . . . . . . . . . . . NUMBER 0020
ACK . . . . . . . . . . . . . . NUMBER 0006
ADDR_6845 . . . . . . . . . . . L WORD 0063 BSEG
ASCII . . . . . . . . . . . . . N PROC 0862 PSEG Length = 0091
BRK . . . . . . . . . . . . . . F PROC 07F5 PSEG Length = 0007
BRK_OFF . . . . . . . . . . . . L WORD 09FB PSEG
BRK_SEG . . . . . . . . . . . . L WORD 09FD PSEG
BUFFER . . . . . . . . . . . . . L BYTE 0E90 PSEG
BUF_SEG . . . . . . . . . . . . L WORD 09F3 PSEG
BYEBYE . . . . . . . . . . . . . L NEAR 040F PSEG
BYPASS . . . . . . . . . . . . . L NEAR 016E PSEG
BYTES . . . . . . . . . . . . . L WORD 09EB PSEG
BYTE_CNT . . . . . . . . . . . . L WORD 0A08 PSEG
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Symbols-2
CAN . . . . . . . . . . . . . . NUMBER 0018
CANCEL . . . . . . . . . . . . . L NEAR 020B PSEG
CAROK . . . . . . . . . . . . . L NEAR 0429 PSEG
CHKMEM . . . . . . . . . . . . . L NEAR 09C5 PSEG
CHKRES . . . . . . . . . . . . . L NEAR 019D PSEG
CHK_EX . . . . . . . . . . . . . L NEAR 031A PSEG
CHK_STA . . . . . . . . . . . . N PROC 0302 PSEG Length = 001A
CLEN . . . . . . . . . . . . . . NUMBER 0004
CLK_EX . . . . . . . . . . . . . L NEAR 04A4 PSEG
CLK_OFF . . . . . . . . . . . . L WORD 09F7 PSEG
CLK_SEG . . . . . . . . . . . . L WORD 09F9 PSEG
CLOCK . . . . . . . . . . . . . L WORD 09EF PSEG
CLOSE . . . . . . . . . . . . . N PROC 0624 PSEG Length = 000A
CLR_BUF . . . . . . . . . . . . N PROC 030C PSEG Length = 0010
CNT_HI . . . . . . . . . . . . . L WORD 09E0 PSEG
CNT_LO . . . . . . . . . . . . . L WORD 09E2 PSEG
CODELOC . . . . . . . . . . . . NUMBER 4000
COLOR . . . . . . . . . . . . . L NEAR 09A5 PSEG
COMINIT . . . . . . . . . . . . L DWORD 0E90 PSEG
COMMA . . . . . . . . . . . . . L NEAR 08E6 PSEG
COMP . . . . . . . . . . . . . . NUMBER 0002
COM_INT . . . . . . . . . . . . L BYTE 0A12 PSEG
COM_MSK . . . . . . . . . . . . L BYTE 0A13 PSEG
CONT0 . . . . . . . . . . . . . L NEAR 0433 PSEG
CONT1 . . . . . . . . . . . . . L NEAR 044A PSEG
CR . . . . . . . . . . . . . . . NUMBER 000D
CRC . . . . . . . . . . . . . . N PROC 044E PSEG Length = 0029
CRC0 . . . . . . . . . . . . . . L NEAR 0463 PSEG
CREATE . . . . . . . . . . . . . L NEAR 0601 PSEG
CREOK . . . . . . . . . . . . . L NEAR 0623 PSEG
CRLF . . . . . . . . . . . . . . L BYTE 0C28 PSEG
CTC_OFF . . . . . . . . . . . . L WORD 09FF PSEG
CTC_SEG . . . . . . . . . . . . L WORD 0A01 PSEG
CTS . . . . . . . . . . . . . . NUMBER 0010
CTSDSR . . . . . . . . . . . . . NUMBER 0030
CUR_POS . . . . . . . . . . . . L WORD 0A0C PSEG
DAT_SEG . . . . . . . . . . . . L WORD 09F5 PSEG
DECD0 . . . . . . . . . . . . . L NEAR 0714 PSEG
DECD1 . . . . . . . . . . . . . L NEAR 0721 PSEG
DECD2 . . . . . . . . . . . . . L NEAR 0722 PSEG
DECODE . . . . . . . . . . . . . N PROC 070F PSEG Length = 001D
DR . . . . . . . . . . . . . . . NUMBER 0001
DSR . . . . . . . . . . . . . . NUMBER 0020
EASY_INT . . . . . . . . . . . . F PROC 02BC PSEG Length = 0046
EAT . . . . . . . . . . . . . . N PROC 0344 PSEG Length = 000C
EAT0 . . . . . . . . . . . . . . L NEAR 034A PSEG
ENABLE . . . . . . . . . . . . . L BYTE 09E4 PSEG
ENCD0 . . . . . . . . . . . . . L NEAR 0732 PSEG
ENCD1 . . . . . . . . . . . . . L NEAR 074D PSEG
ENCD2 . . . . . . . . . . . . . L NEAR 0759 PSEG
ENCD3 . . . . . . . . . . . . . L NEAR 075D PSEG
ENCODE . . . . . . . . . . . . . N PROC 072C PSEG Length = 0038
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Symbols-3
ENDACK . . . . . . . . . . . . . L NEAR 025C PSEG
END_F . . . . . . . . . . . . . L NEAR 0251 PSEG
EOF . . . . . . . . . . . . . . NUMBER 0004
EOT . . . . . . . . . . . . . . NUMBER 0004
ERROR . . . . . . . . . . . . . NUMBER 0080
EXITF . . . . . . . . . . . . . L NEAR 01B0 PSEG
FEND . . . . . . . . . . . . . . L BYTE 09E7 PSEG
FIND_VIDEO . . . . . . . . . . . N PROC 0990 PSEG Length = 004B
FLOW . . . . . . . . . . . . . . N PROC 03E8 PSEG Length = 0066
FLOW0 . . . . . . . . . . . . . L NEAR 03F4 PSEG
FNAME . . . . . . . . . . . . . L BYTE 0CFA PSEG Length = 0040
FORCE . . . . . . . . . . . . . N PROC 02A6 PSEG Length = 0016
GET0 . . . . . . . . . . . . . . L NEAR 0323 PSEG
GET1 . . . . . . . . . . . . . . L NEAR 0341 PSEG
GET2 . . . . . . . . . . . . . . L NEAR 0342 PSEG
GET_ACK . . . . . . . . . . . . N PROC 031C PSEG Length = 0028
GET_INP . . . . . . . . . . . . N PROC 0322 PSEG Length = 0022
HANDLE . . . . . . . . . . . . . L WORD 09F1 PSEG
HOME . . . . . . . . . . . . . . NUMBER 8000
HOT_IN . . . . . . . . . . . . . L NEAR 0552 PSEG
INT_1 . . . . . . . . . . . . . NUMBER 000C
INT_2 . . . . . . . . . . . . . NUMBER 000B
INT_CTL . . . . . . . . . . . . NUMBER 0021
INT_DAT . . . . . . . . . . . . L NEAR 02DD PSEG
INT_EX . . . . . . . . . . . . . L NEAR 02F9 PSEG
INT_FLG . . . . . . . . . . . . L BYTE 09DF PSEG
INT_MS . . . . . . . . . . . . . NUMBER 0008
INT_RC . . . . . . . . . . . . . NUMBER 0001
IRQ3 . . . . . . . . . . . . . . NUMBER 00F7
IRQ4 . . . . . . . . . . . . . . NUMBER 00EF
KILL . . . . . . . . . . . . . . L BYTE 09DD PSEG
KLEN . . . . . . . . . . . . . . NUMBER 000E
LCL_CLK . . . . . . . . . . . . F PROC 0490 PSEG Length = 0019
LF . . . . . . . . . . . . . . . NUMBER 000A
LIN1 . . . . . . . . . . . . . . L BYTE 0A14 PSEG
LINLEN . . . . . . . . . . . . . NUMBER 0017
MAIN . . . . . . . . . . . . . . N PROC 0100 PSEG Length = 0039
MAP . . . . . . . . . . . . . . N PROC 07DE PSEG Length = 0017
MAP0 . . . . . . . . . . . . . . L NEAR 07E3 PSEG
MAP1 . . . . . . . . . . . . . . L NEAR 07EE PSEG
MAX . . . . . . . . . . . . . . NUMBER 000A
MOD_STA . . . . . . . . . . . . L BYTE 09E8 PSEG
MONO . . . . . . . . . . . . . . L NEAR 09D4 PSEG
MS_DOS . . . . . . . . . . . . . NUMBER 0021
NAK . . . . . . . . . . . . . . NUMBER 0015
NFILE0 . . . . . . . . . . . . . L NEAR 05DC PSEG
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Symbols-4
NFILE1 . . . . . . . . . . . . . L NEAR 05EE PSEG
NOCY . . . . . . . . . . . . . . L NEAR 080E PSEG
NODOT . . . . . . . . . . . . . L NEAR 05EB PSEG
NODWN . . . . . . . . . . . . . L NEAR 0653 PSEG
NOENC . . . . . . . . . . . . . L NEAR 0758 PSEG
NONAK . . . . . . . . . . . . . L NEAR 0200 PSEG
NONORM . . . . . . . . . . . . . NUMBER FFFE
NORM . . . . . . . . . . . . . . L NEAR 067C PSEG
NORMAL . . . . . . . . . . . . . NUMBER 0001
NOUP . . . . . . . . . . . . . . L NEAR 0645 PSEG
NOZER . . . . . . . . . . . . . L NEAR 0815 PSEG
OLD_BRK . . . . . . . . . . . . L DWORD 09FB PSEG
OLD_CLK . . . . . . . . . . . . L DWORD 09F7 PSEG
OLD_CTC . . . . . . . . . . . . L DWORD 09FF PSEG
OLD_MASK . . . . . . . . . . . . L BYTE 0A07 PSEG
OLD_UART . . . . . . . . . . . . L DWORD 0A03 PSEG
ONAME . . . . . . . . . . . . . L BYTE 0D3A PSEG Length = 0040
OPEN_R . . . . . . . . . . . . . N PROC 059E PSEG Length = 0023
OPEN_W . . . . . . . . . . . . . N PROC 05C1 PSEG Length = 0063
OPN_OK . . . . . . . . . . . . . L NEAR 05C0 PSEG
ORIGIN . . . . . . . . . . . . . NUMBER 03F6
PARSE . . . . . . . . . . . . . N PROC 0764 PSEG Length = 007A
PARSE0 . . . . . . . . . . . . . L NEAR 0780 PSEG
PARSE1 . . . . . . . . . . . . . L NEAR 0789 PSEG
PARSE2 . . . . . . . . . . . . . L NEAR 07CA PSEG
PARSE3 . . . . . . . . . . . . . L NEAR 07D3 PSEG
PARSEX . . . . . . . . . . . . . L NEAR 079A PSEG
PASS . . . . . . . . . . . . . . L NEAR 08F2 PSEG
PORT . . . . . . . . . . . . . . L WORD 0A10 PSEG
PREXT . . . . . . . . . . . . . L NEAR 03E7 PSEG
PROMPT . . . . . . . . . . . . . N PROC 03D9 PSEG Length = 000F
PRP10 . . . . . . . . . . . . . L BYTE 0C97 PSEG
PRP11 . . . . . . . . . . . . . L BYTE 0CB1 PSEG
PRP12 . . . . . . . . . . . . . L BYTE 0CC9 PSEG
PRP13 . . . . . . . . . . . . . L BYTE 0CDF PSEG
PRP3 . . . . . . . . . . . . . . L BYTE 0AB5 PSEG
PRP4 . . . . . . . . . . . . . . L BYTE 0C2B PSEG
PRP5 . . . . . . . . . . . . . . L BYTE 0C3D PSEG
PRP6 . . . . . . . . . . . . . . L BYTE 0C49 PSEG
PRP7 . . . . . . . . . . . . . . L BYTE 0C5C PSEG
PRP8 . . . . . . . . . . . . . . L BYTE 0C6C PSEG
PRP9 . . . . . . . . . . . . . . L BYTE 0C7E PSEG
RDAT . . . . . . . . . . . . . . NUMBER 0004
RDATA . . . . . . . . . . . . . N PROC 0350 PSEG Length = 0047
RDATA0 . . . . . . . . . . . . . L NEAR 0356 PSEG
RDATA1 . . . . . . . . . . . . . L NEAR 036E PSEG
RDATA2 . . . . . . . . . . . . . L NEAR 0395 PSEG
READ . . . . . . . . . . . . . . N PROC 062E PSEG Length = 0096
READ0 . . . . . . . . . . . . . L NEAR 06B4 PSEG
RECV . . . . . . . . . . . . . . N PROC 01CA PSEG Length = 00AD
RECV0 . . . . . . . . . . . . . L NEAR 01F6 PSEG
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Symbols-5
RECV1 . . . . . . . . . . . . . L NEAR 01FD PSEG
RECV2 . . . . . . . . . . . . . L NEAR 0205 PSEG
RECV3 . . . . . . . . . . . . . L NEAR 0225 PSEG
REC_NOL . . . . . . . . . . . . L WORD 09E9 PSEG
RES0 . . . . . . . . . . . . . . L NEAR 0956 PSEG
RESIT . . . . . . . . . . . . . L NEAR 0943 PSEG
RESP . . . . . . . . . . . . . . N PROC 02A3 PSEG Length = 0019
RESP0 . . . . . . . . . . . . . L NEAR 02B0 PSEG
RES_INT . . . . . . . . . . . . N PROC 054A PSEG Length = 0054
RES_SCR . . . . . . . . . . . . N PROC 093B PSEG Length = 0035
RETRY . . . . . . . . . . . . . NUMBER 0008
RLSD . . . . . . . . . . . . . . NUMBER 0080
RTS_DTR . . . . . . . . . . . . NUMBER 0003
RXSYN0 . . . . . . . . . . . . . L NEAR 03AA PSEG
RXSYN2 . . . . . . . . . . . . . L NEAR 03CB PSEG
RXSYNCH . . . . . . . . . . . . N PROC 0397 PSEG Length = 0036
RXTX . . . . . . . . . . . . . . L BYTE 09EE PSEG
SAV0 . . . . . . . . . . . . . . L NEAR 092D PSEG
SAV_SCR . . . . . . . . . . . . N PROC 08FE PSEG Length = 003D
SCRATTR . . . . . . . . . . . . NUMBER 0070
SCR_ACK . . . . . . . . . . . . NUMBER 055E
SCR_BLK . . . . . . . . . . . . NUMBER 054C
SCR_BUF . . . . . . . . . . . . L BYTE 0AB5 PSEG
SCR_BYT . . . . . . . . . . . . NUMBER 068C
SCR_CPS . . . . . . . . . . . . NUMBER 072C
SCR_LEN . . . . . . . . . . . . NUMBER 05EC
SCR_SAV . . . . . . . . . . . . L BYTE 09DE PSEG
SCR_SEG . . . . . . . . . . . . L WORD 0A0E PSEG
SDATA . . . . . . . . . . . . . N PROC 0277 PSEG Length = 002C
SDATA1 . . . . . . . . . . . . . L NEAR 028F PSEG
SDATA2 . . . . . . . . . . . . . L NEAR 0292 PSEG
SEND . . . . . . . . . . . . . . N PROC 0139 PSEG Length = 0091
SEND0 . . . . . . . . . . . . . L NEAR 0168 PSEG
SEND1 . . . . . . . . . . . . . L NEAR 0173 PSEG
SEND2 . . . . . . . . . . . . . L NEAR 0176 PSEG
SENDX . . . . . . . . . . . . . N PROC 08F3 PSEG Length = 000B
SENDX0 . . . . . . . . . . . . . L NEAR 08F6 PSEG
SET_INT . . . . . . . . . . . . N PROC 04A9 PSEG Length = 00A1
SET_SEG . . . . . . . . . . . . N PROC 0477 PSEG Length = 0019
SHOW . . . . . . . . . . . . . . N PROC 07FC PSEG Length = 0066
SHO_RES . . . . . . . . . . . . N PROC 03CD PSEG Length = 000C
STACKP . . . . . . . . . . . . . L WORD 0E80 PSEG
START . . . . . . . . . . . . . NEAR 0000 PSEG
STATUS . . . . . . . . . . . . . L BYTE 09E6 PSEG
SUBTR . . . . . . . . . . . . . L NEAR 08C5 PSEG
SUBTR1 . . . . . . . . . . . . . L NEAR 08C8 PSEG
SUBTR2 . . . . . . . . . . . . . L NEAR 08DD PSEG
SUBTR3 . . . . . . . . . . . . . L NEAR 08E5 PSEG
SYN . . . . . . . . . . . . . . NUMBER 0016
SYNC . . . . . . . . . . . . . . NUMBER 0040
THRE . . . . . . . . . . . . . . NUMBER 0020
TIMEOUT . . . . . . . . . . . . NUMBER 0010
Microsoft (R) Macro Assembler Version 5.00 9/13/88 21:25:10
JMODEM.ASM Symbols-6
TIMOUT . . . . . . . . . . . . . NUMBER 0012
TIM_L . . . . . . . . . . . . . L WORD 09DB PSEG
TRIES . . . . . . . . . . . . . L BYTE 09ED PSEG
TRISTAT . . . . . . . . . . . . NUMBER 0008
TXSYNCH . . . . . . . . . . . . N PROC 0397 PSEG Length = 0036
UAR_OFF . . . . . . . . . . . . L WORD 0A03 PSEG
UAR_SEG . . . . . . . . . . . . L WORD 0A05 PSEG
VIDEO . . . . . . . . . . . . . NUMBER 0010
WASC . . . . . . . . . . . . . . L BYTE 09E5 PSEG
WASOK . . . . . . . . . . . . . L NEAR 0127 PSEG
WPOINT . . . . . . . . . . . . . L WORD 0A0A PSEG
WRITE . . . . . . . . . . . . . N PROC 06C4 PSEG Length = 004B
WRITE0 . . . . . . . . . . . . . L NEAR 06ED PSEG
WRT0 . . . . . . . . . . . . . . L NEAR 0980 PSEG
WRT1 . . . . . . . . . . . . . . L NEAR 0984 PSEG
WRT_SCR . . . . . . . . . . . . N PROC 0970 PSEG Length = 0020
YES . . . . . . . . . . . . . . L NEAR 079C PSEG
@FILENAME . . . . . . . . . . . TEXT JMODEM
1503 Source Lines
1503 Total Lines
258 Symbols
48786 + 326638 Bytes symbol space free
0 Warning Errors
0 Severe Errors